迭代器 生成器
阿新 • • 發佈:2021-01-20
迭代器
for 迴圈就使用了迭代器協議,將資料轉化為迭代器。
迭代器是訪問集合內元素的一種方式,一般用來遍歷資料。
迭代器訪問與列表的下標訪問不同,迭代器是不能返回的,迭代器提供了一種惰性獲取資料的方式
[]使用了 __getitem__
迭代協議即實現了 __iter__
方法
collections.abc.Iterable
可迭代類即實現了 __iter__
方法
collections.abc.Iterator
迭代器即實現了 __iter__
__next__
方法
class Group(object): '''實現一個迭代器物件''' def __init__(self, employee_list:list): self.iter_list = employee_list self.index = 0 def __iter__(self): return self def __next__(self): # 返回迭代值的函式 try: word = self.iter_list[self.index] except IndexError: raise StopIteration
生成器
有 yield
就是一個生成器函式,返回一個生成器物件。
生成器物件內部實現了迭代器。
def fib2(index): re_list = [] n, a, b = 0, 0, 1 while n < index: re_list.append(b) a, b = b, a+b n += 1 return re_list # 遇到 yield 就返回一個值,之後繼續執行函式 def gen_fib(index): n, a, b = 0, 0, 1 while n < index: yield b a, b = b, a+b n += 1 # print(fib2(500)) for i in gen_fib(100): print(i)
python一切皆物件,棧幀物件,位元組碼物件
用函式呼叫子函式時會建立一個棧幀
所有的棧幀都是分配在堆記憶體上的,這決定了棧幀可以獨立於呼叫者存在
當foo函式呼叫bar函式時,在堆上建立了兩個棧幀物件。
生成器對二者進行了封裝
f_lasti
記錄程式碼上一次執行到的位置
f_locals
記錄區域性變數
前兩者能夠控制函式的執行與暫停。是協程的基礎。
collections.UserList
是一個用python實現的列表物件。其中__iter__
就是使用生成器實現的。
生成器使用案例
# 案例:讀取一個 500G 的檔案,只有一行,通過特殊字元作為分隔符 def myreadlinew(f, newline): buf = "" while True: while newline in buf: pos = buf.index(newline) yield buf[:pos] buf = buf[pos + len(newline)] chunk = f.read(4096*10) if not chunk: # 讀到檔案結尾 yield buf break buf += chunk with open("file.txt") as f: for line in myreadlinew(r, "分隔符"): print(line)