01. Python 迭代器、生成器

01. Python迭代器、生成器

本篇根据菜鸟教程-Python3 迭代器与生成器改写

0.1.1. 迭代器

迭代是Python最强大的功能之一,是访问集合元素的一种方式。迭代器具有以下几种特点:

  1. 是一个可以记住遍历的位置的对象
  2. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束,所有元素访问结束后抛出StopIteration异常。
  3. 只能往前不会后退
  4. 迭代器有两个基本的方法iter() (用于创建迭代器对象)和 next() (遍历下一个迭代器对象)。
  5. 字符串,列表或元组对象都可用于创建迭代器
0.1.1.1. 迭代器创建以及遍历
  1. 使用iter()方法创建迭代器对象
list = [1, 2, 3, 4]   # 创建列表
it = iter(list)    # 创建迭代器对象
print (next(it))   # 输出迭代器的下一个元素
---->
1
print (next(it))
---->
2
  1. 使用for语句正常进行迭代器遍历:
list = [1,2,3,4]
it = iter(list)    # 创建迭代器对象
for x in it:
    print (x, end=" ")
---->
1 2 3 4
  1. 使用next方法进行迭代遍历
import sys         # 引入 sys 模块
 
list = [1,2,3,4]
it = iter(list)    # 创建迭代器对象
 
while True:
    try:
        print (next(it))
    except StopIteration:
        sys.exit()
---->
1
2
3
4

0.1.1.1.1. 创建迭代器

创建迭代器对象时需要在类中实现两个方法:

  1. __iter__()方法:实现了__next__()方法并通过StopIteration异常标识迭代完成;
  2. __next__()方法:会返回下一个迭代器对象;
  • 例:创建数值迭代器,初值为1,逐步增1:
class MyNumbers:
  def __iter__(self):
    self.a = 1       # 类中的 self.a 可随便命名,可以为self.bb等等,只是一个普通的成员属性名,但是上下要一致
    return self
 
  def __next__(self):
    if self.a <= 5:
      x = self.a
      self.a += 1
      return x
    else:
      raise StopIteration
 
myclass = MyNumbers()
myiter = iter(myclass)
 
for x in myiter:
  print(x)
---->
1
2
3
4
5

0.1.2. 生成器

Python 中,使用了 yield 的函数被称为生成器(generator)。生成器是一个返回迭代器的函数只能用于迭代操作,可简单理解为生成器就是一个迭代器。调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。调用一个生成器函数,返回的是一个迭代器对象。

  • 例:使用 yield 实现斐波那契数列:
import sys
 
def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
 
while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()

0.1.3. 生成器与迭代器的异同

对于生成器,Python会自动实现迭代器协议(迭代器协议是指对象需要提供next方法,它要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代; 可迭代对象就是:实现了迭代器协议的对象),以便应用到迭代背景中。由于生成器自动实现了迭代器协议,所以,我们可以调用它的next方法,并且,在没有值可以返回的时候,生成器自动产生StopIteration异常。
状态挂起:生成器使用yield语句返回一个值。yield语句挂起该生成器函数的状态,保留足够的信息,以便之后从它离开的地方继续执行。
对于这一点,当建立生成器,使用若干次next操作后会记住当前的位置,之后继续采用for循环的时候会继续以此断点为起点继续进行,但是迭代器使用若干次next操作后,继续使用for循环会再次从头开始,而不会从断点继续开始。

  1. 生成器会继续断点之后的操作,直至耗尽生成器
class MyNumbers:
    def __iter__(self):
        self.bb = 1
        return self
    def __next__(self):
        if self.bb <= 5:
            x = self.bb
            self.bb += 1
            return x
        else:
            raise StopIteration

myclass = MyNumbers()
myiter = iter(myclass)
gen = enumerate(myiter)  # enumerate会自动将迭代器变为生成器
print(next(gen))
---->
(0, 1)

for i, b in gen:      # 从断点开始
    print(b)
---->
2
3
4
5
  1. 迭代器在之前要是经历过迭代操作,使用for循环进行迭代会再次从头开始迭代,而不是从断点开始;
class MyNumbers:
    def __iter__(self):
        self.bb = 1
        return self
    def __next__(self):
        if self.bb <= 5:
            x = self.bb
            self.bb += 1
            return x
        else:
            raise StopIteration

myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter))
---->
1

for i in myiter:
    print(i)
---->
1
2
3
4
5
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中的迭代器生成器是一种基于惰性计算的概念,它们可以有效地处理大量的数据或者无限序列。下面我将分别介绍迭代器生成器迭代器Iterator)是一个实现了迭代协议(Iterator Protocol)的对象。通过调用内置函数 `iter()` 可以将可迭代对象转换为迭代器迭代器对象可以使用内置函数 `next()` 来逐个访问数据元素,直到没有更多的元素可供访问时,会引发 `StopIteration` 异常。例如,可以使用迭代器来遍历列表、元组、集合等容器类型的数据。 生成器(Generator)则是一种特殊的迭代器。它不需要显式地实现迭代协议,而是通过函数中的 `yield` 关键字来实现惰性计算。生成器函数在每次调用时返回一个值,并在下一次调用时从上一次离开的位置继续执行。这样可以节省大量的内存空间,并且提高程序的效率。生成器函数定义时使用 `def` 关键字,并包含至少一个 `yield` 关键字。 下面是一个简单的示例代码,演示了如何使用迭代器生成器: ```python # 使用迭代器遍历列表 my_list = [1, 2, 3, 4, 5] my_iter = iter(my_list) while True: try: item = next(my_iter) print(item) except StopIteration: break # 使用生成器生成斐波那契数列 def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b fib = fibonacci() for i in range(10): print(next(fib)) ``` 希望以上解释能够帮助你理解迭代器生成器的概念。如果有任何进一步的问题,请随时提问!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值