python生成器和迭代器_Python生成器和迭代器

1、什么是生成器

要说生成器,那就要先看列表,有了列表为啥还要生产器呢。列表可以写成解析式,书写简单,运行速度快,但是列表是一次性生成全部数据,如果数据较大就需要很大的内存。

>>> a=[i*i for i in range(10)]>>a

[0,1, 4, 9, 16, 25, 36, 49, 64, 81]

列表a需要一次把全部数据生成出来,如果数据成千上万就会受限制。

如果列表元素不是一次性全部生成,而是在循环中不断的计算推导出来,那就不需要一次创建列表数组,不需要申请很大的内存空间,这就是生成器。

2、生成器的特点

上面的列表推导式的方括号改为圆括号,就是生成器。

>>> a=(i*i for i in range(10))>>>a at 0x00000224FFB4DB48>

那么怎么从生成器里取数据呢?

>>>next(a)

0>>>next(a)1

>>>next(a)4

>>>next(a)9

>>>next(a)16

>>>next(a)25

生成器generator有一个next方法,每次调用都会计算出他的下一个元素的值。生成器是可以迭代的,所以可以直接使用for语句循环生成器。

>>> a=[i*i for i in range(10)]>>> for i ina:print(i, end=' ')>>> 0 1 4 9 16 25 36 49 64 81

除了使用圆括号创建生成器,也可以用yeild创建生成器,含有yeild关键字的函数都是生成器。生成器其实是一种特殊的迭代器,但是不需要像迭代器一样实现__iter__和__next__方法,只需要使用关键字yield就可以。

defgen_squares(num):for x inrange(num):print("x0=",x)yield x ** 2

print("x1=",x)

调用生成器:

for i in gen_squares(5):print(i)

输出如下,开始x=0,先输出x0=0,然后yeild返回print(i)打印平方数。下次循环回到yeild位置执行输出x1=1,然后循环x=1,输出x0=1,再次yeild到print(i)。

x0=0

0

x1=0

x0= 1

1x1= 1x0= 2

4x1= 2x0= 3

9x1= 3x0= 4

16x1= 4

调用部分做个简单修改:

for i in gen_squares(5):print(i)if i==1:break

输出为如下,可见yield能保存内部状态,并挂起中断退出。在下一轮迭代调用时,从yield的地方继续执行,并且沿用上一轮的函数内部变量的状态,直到内部循环过程结束。

x0=0

0

x1=0

x0= 1

1

python使用生成器对延迟操作提供了支持,需要时才计算,不提前计算,这种做法节约内存空间,但是需要一直调用计算过程,可以说是时间换空间吧。

3、什么是迭代器

实现了__iter__和__next__方法的对象都称为迭代器。迭代器完成迭代功能,基于上一次的结果重复计算,自动记录所在的位置,而不需要手动记录索引,含有__iter__方法的对象都是可迭代对象。

迭代对象内置两个方法:__next__和__iter__方法。next方法可以使迭代器自动记录迭代位置而不需要用户维护索引。iter方法能返回迭代器本身。

迭代器是一个有状态的对象,在调用next() 的时候返回下一个值,如果容器中没有更多元素了,则抛出StopIteration异常。

列表、元组就实现了迭代器。

>>> a=[1,2,3,4]>>> it = a.__iter__()>>>next(it)1

>>>next(it)2

>>>next(it)3

>>>next(it)4

>>>next(it)

Traceback (most recent call last):

File"", line 1, in next(it)

StopIteration

4、实现迭代对象

classsquare:def __init__(self, n):

self.prev=0

self.curr=0

self.n=ndef __iter__(self):returnselfdef __next__(self):if(self.curr

self.prv= self.curr *self.curr

self.curr+=1

returnself.prvelse:raiseStopIteration

a= square(10)for i ina:print(i)print("\r\n-------\r\n")

b= square(5)for i inb:print(i)

输出结果为:

==================== RESTART: C:/Users/plu/my_python/t1.py ====================01

4

9

16

25

36

49

64

81

-------01

4

9

16

>>>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值