RELATEED CONSULTING
相关咨询
选择下列产品马上在线沟通
服务时间:8:30-17:00
你可能遇到了下面的问题
关闭右侧工具栏

新闻中心

这里有您想知道的互联网营销解决方案
python中的生成器是什么-创新互联

创新互联www.cdcxhl.cn八线动态BGP香港云服务器提供商,新人活动买多久送多久,划算不套路!

创新互联坚持“要么做到,要么别承诺”的工作理念,服务领域包括:网站建设、做网站、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的河源网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!

python中的生成器是什么?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

生成器,是一个用来创建迭代器的工具。它简单而强大,类似写函数那样进行定义,但是需要返回数据时不是使用return,而是使用yield语句。

生成器函数

用yield语句返回数据的“函数”,称为生成器函数。我们把上一节中自定义类LessThan改写成生成器函数

In [30]: def lessthan(n): 
    ...:     for i in range(n-1, -1, -1): 
    ...:         yield i 
    ...:          
    ...:

In [31]: for i in lessthan(5): 
    ...:     print(i) 
    ...:
4
3
2
1
0
In [32]: lt = lessthan(3)

## 查看生成器对象的__iter__()和__next__():
In [33]: lt.__iter__?
Signature:      lt.__iter__()
Call signature: lt.__iter__(*args, **kwargs)
Type:           method-wrapper
String form:    
Docstring:      Implement iter(self).

In [34]: lt.__next__?
Signature:      lt.__next__()
Call signature: lt.__next__(*args, **kwargs)
Type:           method-wrapper
String form:    
Docstring:      Implement next(self).

通过生成器改写LessThan类后,代码更加简洁紧凑,因为它自动创建了__iter__()和__next__()方法,通过for循环可以遍历生成器对象。

接下来我们定义一个生成器对象lt,对这个生成器对象调用next(),每一次调用它都会从上次离开的位置回复执行(也就是记住上次执行语句时的所有数据值)。当生成器生成了所有元素(生成器终结)就会引发StopIteration错误。

In [53]: lt = lessthan(3)

In [54]: next(lt)
Out[54]: 2

In [55]: next(lt)
Out[55]: 1

In [56]: next(lt)
Out[56]: 0

In [57]: next(lt)
---------------------------------------------------
StopIteration      Traceback (most recent call last)
 in 
----> 1 next(lt)

StopIteration:

生成器解析式

为了实现一些简单的生成器,我们可以不用函数的形式,而是用类似列表解析式的语法,将外层的方括号用圆括号代替即可。

生成器表达式相比完整的生成器更紧凑但较不灵活,相比等效的列表推导式则更为节省内存。比如下面的的代码,用列表表达式生成的mylist的每个元素都保存在内存中,而mygener每次迭代时才会产生一个元素。假设元素个数不是10,而是100万甚至更多,此时生成器的内存优势会非常明显。

In [41]: mylist = [i*i for i in range(10)]

In [42]: mylist
Out[42]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

In [43]: mygener = (i*i for i in range(10))

In [44]: mygener
Out[44]:  at 0x7fc048be3bf8>

生成器解析式被设计用于生成器将立即被外层函数所使用的情况,比如:

In [45]: sum(i*i for i in range(10))
Out[45]: 285

sum()括号里面的i*i for i in range(10)就是一个生成器解析式,避免生成一个列表而占用过多内存。

同样的,下面的例子中都是使用了生成器解析式:

xvec = [10, 20, 30]
yvec = [7, 5, 3]
sum(x*y for x,y in zip(xvec, yvec))         # dot product

from math import pi, sin
sine_table = {x: sin(x*pi/180) for x in range(0, 91)}

unique_words = set(word  for line in page  for word in line.split())

valedictorian = max((student.gpa, student.name) for student in graduates)

data = 'golf'
list(data[i] for i in range(len(data)-1, -1, -1))

总结

Python提供了两种方式实现生成器:

(1)生成器函数

语法上与普通函数相似,用yield替代return换回值;自动实现迭代器协议:__iter__()方法和__next__()方法。没有值可返回时,引起StopInteration异常。yield语句挂起生成器函数的状态,以便再次迭代时从离开的状态继续执行。

(2)生成器解析式

类似列表解析式,用圆括号替换方括号,从而简单实现简单的生成器。

(3)生成器的优点

代码紧凑,节省内存。不像列表可以多次遍历,生成器只能遍历一遍。

看完上述内容,你们掌握python中的生成器是什么的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联-成都网站建设公司行业资讯频道,感谢各位的阅读!


本文名称:python中的生成器是什么-创新互联
当前链接:http://lswzjz.com/article/ddhgse.html