在Python中,何时应使用生成器表达式,何时应使用列表推导?
# Generator expression
(x*2 for x in range(256))
# List comprehension
[x*2 for x in range(256)]
在Python中,何时应使用生成器表达式,何时应使用列表推导?
# Generator expression
(x*2 for x in range(256))
# List comprehension
[x*2 for x in range(256)]
next()
请求时才进行。在next()
时,生成器对象会立即创建并返回。next()
调用时向您返回一个值,它就完成了,并且不需要再将其存储在内存中。只有一个单独的项目加载到内存中。如果您正在遍历磁盘上的大型文件,如果文件太大,则可能会出现内存问题。在这种情况下,使用生成器表达式会更有效率。我认为大多数答案都忽略了一些东西。列表生成式基本上创建一个列表并将其添加到堆栈中。在列表对象非常大的情况下,您的脚本进程会被终止。在这种情况下,最好使用生成器,因为其值不会存储在内存中,而是作为有状态的函数存储。此外,创作速度;列表推导比生成器推导更慢。
简而言之:如果对象的大小没有过大,则使用列表推导,否则请使用生成器推导。
在函数式编程中,我们希望尽可能少地使用索引。因此,如果我们想要在获取第一批元素后继续使用这些元素,islice() 是更好的选择,因为迭代器状态会被保存。
from itertools import islice
def slice_and_continue(sequence):
ret = []
seq_i = iter(sequence) #create an iterator from the list
seq_slice = islice(seq_i,3) #take first 3 elements and print
for x in seq_slice: print(x),
for x in seq_i: print(x**2), #square the rest of the numbers
slice_and_continue([1,2,3,4,5])
输出:1 2 3 16 25
[exp for x in iter]
只是list((exp for x in iter))
的语法糖吗?还是有执行上的差别? - b0fhX = [x**2 for x in range(5)]; print x
和Y = list(y**2 for y in range(5)); print y
,后者会报错。但在Python3中,列表解析确实是你所期望的被馈送到list()
函数中的生成器表达式的语法糖,因此循环变量将不会再泄漏出来。详见PEP 0289。 - Bas Swinckels