这一篇讲的比较详细:
这两篇也很好:
Python函数式编程指南(三):迭代器
Python函数式编程指南(四):生成器
生成器函数:
返回的是一个生成器(generator),接下来每次对他调用next,那么就会返回一个值,一直到抛出StopIteration为止。
好处:
生成器不会一次性生成所有元素,所以占用很少内存。( i**2 for i in range(3))
列表表达式,一次性生成所有元素,所以占用大量内存。[ i**2 for in range(3) ],不同之处,就是方括号/圆括号。所以还是写yield比较清楚!
一段小程序:
-
def gen01(N):
-
for i in range(N):
-
yield i ** 2
-
-
def gen02(N):
-
return (i**2 for i in range(N)) # 生成器表达式
-
-
a=gen01(4) # 将这一行替换成下一行,执行结果是一样的
-
# a=gen02(4)
-
-
print type(a),dir(a)
-
print a.next(), next(a) # a.next() 与 next(a)
-
print list(a) # list(a) 执行完,再次运行就会抛出StopIteration
-
-
try:
-
print a.next()
-
except StopIteration:
-
print "--- out of scope ---"
-
-
try:
-
print next(a)
-
except StopIteration:
-
print "--- out of scope again ---"
-
-
for item in gen01(5):
-
print ">>", item,
-
print ""
-
for item in gen02(5):
-
print ">>", item,
-
print ""
-
print "sum[0,1,3,4,5]: ", sum(gen02(5)) # 累加
输出:
-
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'next', 'send', 'throw']
-
0 1
-
[4, 9]
-
--- out of scope ---
-
--- out of scope again ---
-
>> 0 >> 1 >> 4 >> 9 >> 16
-
>> 0 >> 1 >> 4 >> 9 >> 16
-
sum[0,1,3,4,5]: 30
下面这个也是开篇提到的那边文章中的例子,乍一看,晕;运行一遍,仍旧觉得很神奇
,目前我也没猜测出内部是怎么实现的。。。
-
def index_words_02(text):
-
if text:
-
yield 0
-
for index, letter in enumerate(text, 1):
-
if letter == ' ':
-
yield index
-
-
cc = index_words_02("hello good bye")
-
print type(cc), next(cc), cc.next(), next(cc)
-
try:
-
print next(cc)
-
except StopIteration:
-
print "---- Out of range ----"
输出:
-
<type 'generator'> 0 6 11
-
---- Out of range ----
阅读(1613) | 评论(0) | 转发(0) |