range()(或 Python2.x 中的xrange())返回的对象称为惰性迭代。
生成器不是将整个范围[0,1,2,..,9] 存储在内存中,而是存储(i=0; i<10; i+=1) 的定义并仅在需要时计算下一个值(也称为惰性求值)。
本质上,生成器允许您返回类似结构的列表,但这里有一些区别:
- 列表在创建时存储所有元素。生成器会在需要时生成下一个元素。
- 列表可以根据需要进行多次迭代,生成器只能恰好迭代一次。
- 列表可以通过索引获取元素,而生成器不能——它只生成一次值,从开始到结束。
可以通过两种方式创建生成器:
(1) 非常类似于列表推导:
# this is a list, create all 5000000 x/2 values immediately, uses []
lis = [x/2 for x in range(5000000)]
# this is a generator, creates each x/2 value only when it is needed, uses ()
gen = (x/2 for x in range(5000000))
(2) 作为函数,使用yield返回下一个值:
# this is also a generator, it will run until a yield occurs, and return that result.
# on the next call it picks up where it left off and continues until a yield occurs...
def divby2(n):
num = 0
while num < n:
yield num/2
num += 1
# same as (x/2 for x in range(5000000))
print divby2(5000000)
注意:尽管range(5000000) 是 Python3.x 中的生成器,[x/2 for x in range(5000000)] 仍然是一个列表。 range(...) 完成它的工作并一次生成一个 x,但在创建此列表时将计算整个 x/2 值列表。