Appearance
生成器
函数体中出现 yield 时,它是生成器函数。调用函数不会立即执行函数体,而是返回生成器对象;生成器本身就是迭代器。
py
def gen_num():
print('start generator')
yield 1
yield 2
yield 3
return 4
print(gen_num)
gen = gen_num() # 生成器对象
print(gen)
print(next(gen))
print(next(gen))
print(next(gen))
# try:
# print(next(gen))
# except StopIteration as e:
# print('generator return value:',e.value)每次调用 next(gen),生成器从上次暂停处继续,运行到下一个 yield 后再次暂停并产出值。函数结束后生成器耗尽,不能重新开始。
用生成器实现 __iter__
生成器可以代替手写的迭代器类:
py
import re
WORD_RE = re.compile(r'\w+')
class Sentence:
def __init__(self, text: str) -> None:
self.text = text
self.words = WORD_RE.findall(text)
def __iter__(self):
for word in self.words:
yield word
s = Sentence("Hi ice, Hello World!")
it1 = iter(s)
# for word in s:
# print(word)
# for word in s:
# print(word)
for word in it1:
print(word)
for word in it1:
print(word)每次 iter(sentence) 都会创建新的生成器,因此同一个 Sentence 可以重复遍历。
惰性产生结果
findall() 会先创建完整的匹配列表;finditer() 配合生成器会按需产生每个匹配结果:
py
from pydoc import text
import re
WORD_RE = re.compile(r'\w+')
class Sentence:
def __init__(self, text: str) -> None:
self.text = text
def __iter__(self):
# for match in WORD_RE.finditer(self.text):
# yield match.group()
return (match.group() for match in WORD_RE.finditer(self.text))
s = Sentence("Hi ice, Hello World!")
for word in s:
print(word)
print('-------------')
for word in s:
print(word)适合大文件、流式数据和计算成本较高的数据。
生成器表达式
生成器表达式使用圆括号,结果按需产生;列表推导会立即创建完整列表。
python
squares = (x * x for x in range(5))