Python生成器

Python生成器,第1张

  • 对列表生成式,可以生成一个列表,可是它所占优的内存是有限的,如果想要保存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]


  • 对列表生成式来,可以将其中的元素一个个打印出来,那么对于生成器呢?同样地,也可以将其值一个个输出
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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/921461.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存