关于如何使用Python生成器的学习笔记和示例代码
《Effect Python 编写高质量Python代码的59个有效方法》。主要记录生成器的使用方法以及示例代码。
返回队列的函数
如果函数要生成结果数组,最简单的方法是将这些结构放入列表中并将其返回给调用者。
def index_words(text):
"""用append方法将这些此的首字母索引添加到result列表中,并在函数结束时将其返回给调用者。"""
result = []
if text:
result.append(0)
for index, letter in enumerate(text):
if letter == ' ':
result.append(index+1)
return result输入一些测试值,验证函数是否可以正常运行:
>address = 'Four score and seven years ago...' result = index_words(address) print(result[:3])
打印
[0, 5, 11]
生成器函数
这个函数使用生成器而不是编写更好。生成器是使用表达式 yield 的函数。当调用生成器函数时,它实际上并不运行,而是返回一个迭代器。每当在此迭代器上调用内置 next 函数时,迭代器都会将生成器前进到下一个 yield 表达式。从生成器传递到 yield 的每个值都将由迭代器返回给调用者。
def index_words_iter(text):
if text:
yield 0
for index, letter in enumerate(text):
if letter == ' ':
yield index + 1result = list(index_words_iter(address))
注意:生成器函数返回的迭代器是有状态的,调用者不应重复使用。
因为迭代器只能产生一轮结果。如果在抛出 StopIteration 异常的迭代器或生成器上继续迭代第二轮,将不会有结果。为了解决这个问题,我们可以显式地使用这个迭代器创建一个列表,循环遍历整个内容一次,将其分配给这个列表,然后对复制的数据列表进行多次迭代。
实现类的生成器
下面是一个可迭代的容器类,用于从文件中读取每一行数据。
class ReadFileLines(object):
"""
可以迭代的容器类,从文件中获取数据
"""
def __init__(self, path):
self.path = path
def __iter__(self):
with open(self.path) as f:
for line in f:
yield line多次迭代
如果您想多次迭代生成器数据,可以使用以下函数。该函数会将所有数据增量复制到生成器,然后返回一个队列数据。
def normalize_defensive(datas):
"""
从生成器返回一份可以多次迭代的数据
:param datas:容器
:return: result:队列(list)
"""
# 确保调用者传进来的参数,并不是迭代器对象本身
if iter(datas) is iter(datas):
raise TypeError('Must supply a container')
# TODO
result = []
for data in datas:
# TODO
result.append(data)
return result 版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网
