python-迭代器和生成器


一、可迭代对象

  1. python2中的range()和xrange():
    range()的结果是一次全部生成,比较费内存。
    xrange()的结果是一个一个生成,省内存。(通过next一次只取一个值)
    通俗一点来说吧,你去买橘子,你说老板我要十个橘子,range()就是老板装了10个一次性给你,xrange()就是老板一个一个给你,直到够了十个为止。懂了吗,我去买几个橘子,你就站在此地,不要走动。

只要有 iter 方法的都是可迭代对象。
可以被for循环的都是可迭代对象,严格的来说for是迭代,可以自动执行 iternext

二、迭代器

  • 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
  • 迭代器有两个基本的方法:****。迭代器可以被for迭代,for迭代迭代器时,会执行 next 方法

迭代器是如何迭代的?

  • 通过 next 方法记住迭代的位置,有没有迭代完毕。

三、生成器

生成器的介绍

根据制定的规则循环生成数据,当条件不成立时则生成数据结束。数据不是一次性全部生成处理,而是使用一个,再生成一个,可以节约大量的内存。

创建生成器的方式

方式一

# 创建生成器
my_generator = (i * 2 for i in range(5))
print(my_generator)

# next获取生成器下一个值
# value = next(my_generator)
# print(value)

# 遍历生成器
for value in my_generator:
    print(value)

代码说明:

  • next 函数获取生成器中的下一个值
  • for 循环遍历生成器中的每一个值

运行结果:

<generator object <genexpr> at 0x101367048>
0
2
4
6
8

方式二-yield

只要在def函数里面看到有 yield 关键字那么就是生成器

def mygenerater(n):
    for i in range(n):
        print('开始生成...')
        yield i # 代码执行完这句会暂停,再次启动时继续执行
        print('完成一次...')

if __name__ == '__main__':
    g = mygenerater(2)
    # 获取生成器中下一个值
    # result = next(g)
    # print(result)

    # while True:
    #     try:
    #         result = next(g)
    #         print(result)
    #     except StopIteration as e:
    #         break

    # # for遍历生成器, for 循环内部自动处理了停止迭代异常,使用起来更加方便
    for i in g:
        print(i)

代码说明:

  • 代码执行到 yield 会暂停,然后把结果返回出去,下次启动生成器会在暂停的位置继续往下执行
  • 生成器如果把数据生成完成,再次获取生成器中的下一个数据会抛出一个StopIteration 异常,表示停止迭代异常
  • while 循环内部没有处理异常操作,需要手动添加处理异常操作
  • for 循环内部自动处理了停止迭代异常,使用起来更加方便,推荐大家使用。

运行结果:

开始生成...
0
完成一次...
开始生成...
1
完成一次...

生成器的使用场景

数学中有个著名的斐波拉契数列(Fibonacci),数列中第一个数为0,第二个数为1,其后的每一个数都可由前两个数相加得到:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …

现在我们使用生成器来实现这个斐波那契数列,每次取值都通过算法来生成下一个数据, 生成器每次调用只生成一个数据,可以节省大量的内存。

def fibonacci(num):
    a = 0
    b = 1

    # 记录生成fibonacci数字的下标
    current_index = 0

    while current_index < num:
        result = a
        a, b = b, a + b
        current_index += 1
        # 代码执行到yield会暂停,然后把结果返回出去,下次启动生成器会在暂停的位置继续往下执行
        yield result


fib = fibonacci(5)
# 遍历生成的数据
for value in fib:
    print(value)

运行结果:

0
1
1
2
3
  • 使用场景:
    一个大文件,边下载边保存。

  • yield和return:
    yield返回数据,可以继续执行余下的代码
    return返回数据,结束该代码块,不会继续执行该代码块余下的代码

总结

可迭代对象、迭代器和生成器的关系:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值