关于如何使用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 + 1
result = 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前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。