一. 什么是生成器和迭代器
使用一个可迭代的对象比一个列表的好处:
还记得前面的filter和map吗,他们的返回值是一个相应的对象,我们可以循环这个对象,就取到了每个对象元素,而且取完之后,这个元素就没啦,一边取值,一边垃圾回收,这样相对于返回值直接是一个列表,就大大的节省了内存。因为如果返回值是一个长度几万几十万的列表,会一下子在内存里开辟那么多的内存空间,但是如果生成的是一个filter或者map对象,就没有这个担心啦。
我们用一个小例子来进行对比:
1
#
要用python2.7的环境
2
#
py3中range和xrange合并啦,不再有xrange,range的返回值是range对象,不再是list
3
4 ret=range(0,10)
5print ret
6print type(ret)
7 8 ret=xrange(0,10)
9print ret
10print type(ret)
1112执行结果:
13 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
14 <type ‘list‘>
15 xrange(10)
16 <type ‘xrange‘>
1718#可以明显看出生成一个可迭代的对象要比生成一个list对内存的占用少的多,xrange的话,取完一个值,用完之后,就会垃圾回收。
生成器就可以实现这个功能。那么什么是生成器呢?
生成器是一次生成一个值的特殊类型函数。标志性的单词就是yield。
迭代器就是利用next来从生成器里取数据。
1
def
f1():
2
print("生成第一个数")
3yield 1
4print("生成第二个数")
5yield 2
6print("生成第三个数")
7yield 3
8 ret=f1()
9#执行f1()的时候,3个print都没有输出,生成器是一种特殊的函数10print(ret)
11#生成器生成的ret是一个生成器对象,这个对象可以迭代12print("*"*10)
13print(list(ret))
14print(list(ret))
1516执行结果:
17 <generator object f1 at 0x102189c50>
18 **********
19生成第一个数
20生成第二个数
21生成第三个数
22 [1, 2, 3]
23[]
2425def f1():
26print("生成第一个数")
27yield 1
28print("生成第二个数")
29yield 2
30print("生成第三个数")
31yield 3
32 ret=f1()
33#生成器可以配合__next__使用34 r1=ret.__next__()
35print(r1)
36#r1:ret.__next__() 会找到函数中的第一个yield,执行函数到这个yield为止,并将yield后面的数据返回37 r2=ret.__next__()
38print(r2)
39#r2:ret.__next__() 会执行上一个yield下面的代码直到遇到下一个yield,同上会返回yield后面的数据4041执行结果:
42生成第一个数
43 1
44生成第二个数
45 2
注意:实际使用的时候是不需要我们一个一个的_next_的,for循环帮我们做了next,也可以说for循环封装了迭代器。
二. 生成器小例子
1
def
zyrange(m,n):
2
while
True:
3
yield
m
4 m+=1
5if m == n:
6break 7 8for i in zyrange(4,10):
9print(i)
1011执行结果:
12 4
13 5
14 6
15 7
16 8
17 9
原文:http://www.cnblogs.com/meitangyanyan/p/6475892.html
【说明】:本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!