Code前端首页关于Code前端联系我们

关于如何使用Python生成器的学习笔记和示例代码

terry 2年前 (2023-09-25) 阅读数 50 #后端开发

《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前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门