Python入门(二十一):迭代对象(迭代器与生成器)

点击跳转
《Python入门系列目录》



1. 迭代器

  • 迭代是访问集合元素的一种方式

  • 实现了_iter_()的对象是可迭代对象(iterable)

    • 使用内置函数iter(iterable)可以返回可迭代对象iterable的迭代器
  • 使用了_next_()的对象是迭代器

    • 使用内置函数next()可以依次返回迭代器对象的下一个项目值,如果没有新项目,则将导致stopiteration
  • 迭代器是一个可以记住遍历的位置的对象

  • 迭代器只能往前,不能后退

L = [1, 2, 3]
it = iter(L)
print(it)           # <list_iterator object at 0x0000025857313148>
print(next(it))     # 1
print(next(it))     # 2
print(next(it))     # 3
print(next(it))     # 出错:StopIteration

2. 自定义可迭代对象和迭代器

  • 迭代器对象必须实现两个方法:_iter_()和_next__(),二者合称为迭代器协议
  • _iter_()用于返回对象本身,以方便for语句进行迭代
  • _next_()用于返回下一元素
  • 声明一个类,定义上述两个方法,创建该类的对象,即是可迭代对象,也是迭代
class Fib:
    def __init__(self):
        self.a, self.b = 0, 1  # 前两项值
    def __next__(self):
        self.a, self.b = self.b, self.a + self.b    # 此处self.a+self.b是未改变的self.a加self.b,顺序为从左到右
        return self.a   # f(n)=f(n-1)+f(n-2)
    def __iter__(self):
        return self

# 测试代码
fibs = Fib()    # fibs为可迭代对象
for f in fibs:
    if f < 1000:
        print(f, end=',')   # 1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
    else:
        break

3. 生成器

  • 生成器函数使用yield语句返回一个值,然后保存当前函数整个执行状态,等待下一次调用
  • 普通函数用return返回,生成器函数用yield返回,一次只能返回一个结果
  • 生成器函数是一个迭代器,是可迭代对象,支持迭代
  • 调用时返回生成器对象
def gentripls(n):
    for i in range(n):
        yield i*3

f = gentripls(10)
print(f)        # <generator object gentripls at 0x000001951632EEC8>
i = iter(f)     # 通过内置函数iter获得iterator
print(next(i))  # 通过内置函数next获得下一个项目 0
print(next(i))  # 通过内置函数next获得下一个项目 3
for t in f:
    print(t, end=' ')   # 6 9 12 15 18 21 24 27 
# 生成器函数创建斐波那契数列
def fib():
    a,b = 0,1 # 前两项值
    while 1:
        a,b = b,a+b
        yield a #f(n)=f(n-1)+f(n-2)
#测试代码
for f in fib():
    if f < 1000: 
        print(f, end=',')   # 1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
    else:
        break
  • 生成器的优点

    • 节省内存,特别是大量数据的时候,只有在用的时候进行生成
    • 节省代码
    • 模拟并发
  • 生成器表达式

    • 类似于列表解析式,不过用圆括号括起来

    • 返回的是一个可迭代对象

      gen = (i*2 for i in range(1, 10))
      print(gen)  # <generator object <genexpr> at 0x0000019D4EB6E348>
      for e in gen:
          print(e, end=",")   # 2,4,6,8,10,12,14,16,18,
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值