生成器的作用是节约内存,防止程序内存膨胀,在访问速度上和sequance应该是类似的。
For instance, the following summation code will build a full list of squares in memory, iterate over those values, and, when the reference is no longer needed, delete the list:
sum([x*x for x in range(10)])
Memory is conserved by using a generator expression instead:
sum(x*x for x in range(10))从上面的例子我们可以看出, 使用”()“表达式产生的生成器最终的效果是和使用list作为参数是一样的,但是内存降低许多。
Similar benefits are conferred on constructors for container objects:
s = Set(word for line in page for word in line.split()) d = dict( (k, func(k)) for k in keylist)在容器的初始化方面也有优势。
Generator expressions are especially useful with functions like sum(), min(), and max() that reduce an iterable input to a single value:
max(len(line) for line in file if line.strip())生成器在像sum,max,min这些函数的使用时很有用,它使得函数输入从一个迭代器降低到一个表达式就行了。
Generator expressions also address some examples of functionals coded with lambda:
reduce(lambda s, a: s + a.myattr, data, 0) reduce(lambda s, a: s + a[3], data, 0)
These simplify to:
sum(a.myattr for a in data) sum(a[3] for a in data)在有些需要使用lampda函数的场合,使用生成器可以完全替代。
有关生成器的一些细节:
The semantics of a generator expression are equivalent to creating an anonymous generator function and calling it. For example:
g = (x**2 for x in range(10)) print g.next()
is equivalent to:
def __gen(exp): for x in exp: yield x**2 g = __gen(iter(range(10))) print g.next()使用”()"产生匿名生成器。
Only the outermost for-expression is evaluated immediately, the other expressions are deferred until the generator is run:
g = (tgtexp for var1 in exp1 if exp2 for var2 in exp3 if exp4)
is equivalent to:
def __gen(bound_exp): for var1 in bound_exp: if exp2: for var2 in exp3: if exp4: yield tgtexp g = __gen(iter(exp1)) del __gen相比之下,使用匿名生成器代码非常简洁易懂。
This means that you can write:
sum(x**2 for x in range(10))
but you would have to write:
reduce(operator.add, (x**2 for x in range(10)))
and also:
g = (x**2 for x in range(10))匿名生成器的规则,如果匿名生成器两边本来就有括号,那就不需要再添加括号了,否则一定要添加小括号。
List comprehensions will remain unchanged. For example:
[x for x in S] # This is a list comprehension. [(x for x in S)] # This is a list containing one generator # expression.前者代表list表达式,后者代表生成器表达式。
Unfortunately, there is currently a slight syntactic difference. The expression:
[x for x in 1, 2, 3]
is legal, meaning:
[x for x in (1, 2, 3)]
But generator expressions will not allow the former version:
(x for x in 1, 2, 3)
is illegal.
存在一些语法上的不一致,比如前面的list表达式是合法的,而后面同样的生成器表达式确实 非法的, 需要特别注意。