含有雙下劃線方法__iter__()方法的都是可迭代函數
內部含有__next__和__iter__方法的就是迭代器spa
# 判斷是否函數__iter__方法 print("__iter__" in dir(int)) print("__iter__" in dir(bool)) print("__iter__" in dir(list)) print("__iter__" in dir(dict)) print("__iter__" in dir(set)) print("__iter__" in dir(tuple)) print("__iter__" in dir(enumerate([]))) print("__iter__" in dir(range(1)))
print([]) print([].__iter__()) # 使用__iter__方法後,返回值爲一個迭代器 print(set(dir([].__iter__())) - set(dir([]))) # {'__setstate__', '__length_hint__', '__next__'} print([1, 2, 'aas', 'a'].__iter__().__length_hint__()) # 返回元素的個數 # 迭代器使用next方法,能夠遍歷值 l = [1, 2, 3, 4] iterator = l.__iter__() print(iterator.__next__()) print(iterator.__next__()) print(iterator.__next__()) print(iterator.__next__()) print(iterator.__next__()) # 迭代器返回值完畢後,程序報錯「StopIteration」
Iterable 可迭代的 -- > __iter__ 只要含有__iter__方法的都是可迭代的
[].__iter__() 迭代器 -- > __next__ 經過next就能夠從迭代器中一個一個的取值code
print(range(100000000000000)) print(list(range(1000000000)))
運行上述代碼,能夠看到,第一個迭代器的時候,很快就返回告終果 range(0, 100000000000000)blog
第二段代碼,機子跑死機了,都沒法正常運行ip
含有yiled關鍵字的函數都是生成器函數內存
#正常函數 def generaor(): print('1') return 'a' ret=generaor() print(ret)
還有yiled關鍵字時,不能含有return關鍵字get
def generaor(): print('1') yield 'a' # 替換return關鍵字未yield關鍵字後,就是一個生成器 ret=generaor() print(ret)
def generaor(): print('1') yield 'a' # 替換return關鍵字未yield關鍵字後,就是一個生成器 ret=generaor() print(ret) print("next get value:", ret.__next__()) # 生成器使用next函數獲取值
生成器中,使用雙下線方法來獲取返回值generator
含有多個yield時,每次使用__next__都是到yield時,中止執行,返回值。it
單生成器中的值返回完畢時,報錯StopIterationio
def generaor(): print('1') yield 'a' # 替換return關鍵字未yield關鍵字後,就是一個生成器 print('2') yield 'b' yield 'c' ret=generaor() print(ret) print("next get value:", ret.__next__()) # 生成器使用next函數獲取值 # 1 # next get value: a print("next get value:", ret.__next__()) # 生成器使用next函數獲取值 # 2 # next get value: b print("next get value:", ret.__next__()) # 生成器使用next函數獲取值 # next get value: c # print("next get value:", ret.__next__()) # 生成器使用next函數獲取值 # 報錯StopIteration,生成器到達最後的值報錯
同時定義多個生成器時,多個生成器間並不矛盾,每一個都能獲取各自獨立的值
def bear(): for i in range(20000): yield "bear %s" % i g = bear() g2 = bear() print('生成器函數1:%s' % g.__next__()) print('生成器函數1:%s' % g.__next__()) print('生成器函數2:%s' % g2.__next__()) print('生成器函數2:%s' % g2.__next__()) print('生成器函數1:%s' % g.__next__())
總結:
迭代器:
生成器:
生成器的本質是一個迭代器
從生成器中取數的幾個方法:
練習:
def tail(filename): with open(filename) as f: while True: line = f.readline() line = line.strip() if line: yield line res = tail('file') for line in res: if 'bear' in line: print('***', line)
def generator(): for i in range(2000000000): yield "hello, bear %s" % i g = generator() print(g.__next__()) n = 0 for content in g: n += 1 if n > 50: break print(content)