迭代器和生成器

1、迭代器

定义:访问集合元素的一种方式。迭代器是一个可以记住遍历位置的对象。迭代器对象从第一个元素开始访问,直到所有元素被访问。

运用的场景:

迭代器是一个对象,它能够在遍历数据集合时按需生成值,而不是一次性将所有值存储在内存中。这使得迭代器特别适合处理大数据集合或者是需要延迟计算的情况。

实际中的应用包括:

  1. 处理大数据集合: 当数据集合很大时,通过迭代器可以逐个处理数据,而不必一次性加载整个数据集到内存中,节省内存空间。

  2. 流式处理数据: 在需要连续处理数据流的情况下,迭代器允许逐个获取数据项,例如从文件或网络流中读取数据。

  3. 惰性计算: 当需要进行惰性计算(lazy evaluation)时,迭代器可以根据需要逐步生成结果,而不需要一次性生成所有可能的结果。

  4. 无限序列: 可以使用迭代器来表示和处理无限序列,例如斐波那契数列等。

迭代器有两个基本的方法:iter()和next()

(1)使用iter()或者next() 函数可以将可迭代对象(如列表、字典、字符串等)转换为迭代器

>>> list=[1,2,3,4]
>>> it = iter(list)    # 创建迭代器对象
>>> print (next(it))   # 输出迭代器的下一个元素
1
>>> print (next(it))
2
>>>

#!/usr/bin/python3
 
import sys         # 引入 sys 模块
 
list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
 
while True:
    try:
        print (next(it))
    except StopIteration:
        sys.exit()

也可以使用常规for语句进行遍历:

#!/usr/bin/python3
 
list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
for x in it:
    print (x, end=" ")

(2)面向对象时

把一个类作为一个迭代器使用需要在类中实现两个方法 iter() 与 next() 。

class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self
 
  def __next__(self):
    x = self.a
    self.a += 1
    return x
 
myclass = MyNumbers()
myiter = iter(myclass)
 
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))

定义:StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 next() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。

class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self
 
  def __next__(self):
    if self.a <= 20:
      x = self.a
      self.a += 1
      return x
    else:
      raise StopIteration
 
myclass = MyNumbers()
myiter = iter(myclass)
 
for x in myiter:
  print(x)

2、生成器

定义:

在 Python 中,使用了 yield 的函数被称为生成器(generator)。

yield 是一个关键字,用于定义生成器函数,生成器函数是一种特殊的函数,可以在迭代过程中逐步产生值,而不是一次性返回所有结果。

跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

当在生成器函数中使用 yield 语句时,函数的执行将会暂停,并将 yield 后面的表达式作为当前迭代的值返回。

然后,每次调用生成器的 next() 方法或使用 for 循环进行迭代时,函数会从上次暂停的地方继续执行,直到再次遇到 yield 语句。这样,生成器函数可以逐步产生值,而不需要一次性计算并返回所有结果。

调用一个生成器函数,返回的是一个迭代器对象。

def countdown(n):
    while n > 0:
        yield n
        n -= 1
 
# 创建生成器对象
generator = countdown(5)
 
# 通过迭代生成器获取值
print(next(generator))  # 输出: 5
print(next(generator))  # 输出: 4
print(next(generator))  # 输出: 3
 
# 使用 for 循环迭代生成器
for value in generator:
    print(value)  # 输出: 2 1

以上实例中,countdown 函数是一个生成器函数。它使用 yield 语句逐步产生从 n 到 1 的倒数数字。在每次调用 yield 语句时,函数会返回当前的倒数值,并在下一次调用时从上次暂停的地方继续执行。

通过创建生成器对象并使用 next() 函数或 for 循环迭代生成器,我们可以逐步获取生成器函数产生的值。在这个例子中,我们首先使用 next() 函数获取前三个倒数值,然后通过 for 循环获取剩下的两个倒数值。

生成器函数的优势是它们可以按需生成值,避免一次性生成大量数据并占用大量内存。此外,生成器还可以与其他迭代工具(如for循环)无缝配合使用,提供简洁和高效的迭代方式。

运用的场景:

生成器是一种特殊的迭代器,它可以通过函数来创建。生成器函数使用yield 关键字来返回值,而不是 return,这使得它可以暂停并在需要时继续执行,从而节省内存并提高效率。

实际中的应用包括:

  1. 迭代大数据集合: 生成器函数可以用于生成大数据集合的元素,而不需要一次性将所有数据存储在内存中。

  2. 异步编程: 在异步编程中,生成器可以与协程一起使用,提供一种轻量级的并发编程模型。

  3. 无限序列生成: 可以轻松地创建表示无限序列的生成器,如素数生成器、递增序列等。

  4. 延迟计算: 生成器允许按需生成结果,支持惰性计算,适合处理大数据流或者需要逐步处理的情况。

示例场景
  • 文件处理: 使用生成器可以逐行读取大文件,而不会将整个文件加载到内存中。

  • 数据处理管道: 可以通过生成器函数将数据处理步骤串联起来,每个生成器负责一个步骤,实现高效的数据处理流水线。

  • 并发编程: 使用生成器和协程可以实现高效的并发模型,例如异步任务处理或者事件驱动的编程。

迭代器和生成器提供了处理大数据和惰性计算的有效工具,可以显著提高程序的性能和效率,特别是在需要处理大数据集或者需要高效处理数据流的情况下。

  • 19
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值