Python生成器

  • 对列表生成式,可以生成一个列表,可是它所占优的内存是有限的,如果想要保存1万,10万,100万甚至更多数据时,用列表生成式就不太现实了。不仅造成空间的浪费,而且对后面不会用到的数据就浪费掉了。
  • 生成器与列表生成式在写法上的区别是将[]改成()
  • 条件是它的内部元素是可以根据某种算法推算而出,它的特点是一边循环一遍计算.
l=[x*x for x in range(10)]
print(l)

r=(x*x for x in range(10))
print(r)

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
<generator object at 0x000002000ECD2E40>


  • 对列表生成式来,可以将其中的元素一个个打印出来,那么对于生成器呢?同样地,也可以将其值一个个输出
next()
  • 可以通过next()函数获得生成器的下一个返回值
r=(x*x for x in range(10))
print(next(r))
print(next(r))
print(next(r))
print(next(r))
print(next(r))
print(next(r))
print(next(r))
print(next(r))
print(next(r))
print(next(r))

0
1
4
9
16
25
36
49
64
81

  • 需要注意的是,如果计算到最后一个元素,下一次无元素输出时,会抛出StopIteration 的异常
    在这里插入图片描述
for循环
  • 不断调⽤ next() 实在是太繁琐了,虽然是点一次出现一次,但正确的⽅法是使⽤ for 循环,因为⽣成器也是可迭代对象
    • 判断是否是可迭代对象可以使用Python的内置函数
r=(x*x for x in range(10))
from collections.abc import Iterable
print(isinstance(r,Iterable))

True

  • 创建一个生成器后,用for循环来迭代,并且不用担心StopIteration 异常
r=(x*x for x in range(10))
for rr in r:
    print(rr)

0
1
4
9
16
25
36
49
64
81

next()
r=(x*x for x in range(10))
print(r.__next__())
send()
  • send()第一次调用时里面的参数要为空,随后的不返回空
r=(x*x for x in range(10))
print(r.send(None))
print(r.send(''))

0
1



yield

  • 如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。
    比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:1, 1, 2, 3, 5, 8, 13, 21, 34, …
    斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:
def fib(times):
    a,b=0,1
    n=0
    while(n<times):
        print(b)
        a,b=b,a+b
        n+=1
#调用函数
print(fib(5))

1
1
2
3
5
None

  • 仔细观察,可以看出,fib_a函数实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。也就是说,上面的函数和generator仅一步之遥。要把fib函数变成generator,只需要把print(b)改为yield(b)就可以了
def fib(times):
    a,b=0,1
    n=0
    while(n<times):
        yield(b)
        a,b=b,a+b
        n+=1
#调用函数
print(fib(5))
  • 对其进行输出也同样可以使用上述的4种方法,但一般地很少会使用next(),–next–(),send(),使用for循环会迭代会更便捷
def fib(times):
    a,b=0,1
    n=0
    while(n<times):
        yield(b)
        a,b=b,a+b
        n+=1
#调用函数
for r in fib(5):
    print(r)

1
1
2
3
5

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值