在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)]
当前回答
当结果需要多次迭代时,或者在速度非常重要的情况下,使用列表推导式。在范围较大或无穷大的地方使用生成器表达式。
有关更多信息,请参阅生成器表达式和列表推导式。
其他回答
对于函数式编程,我们希望使用尽可能少的索引。因此,如果我们想在获取元素的第一个切片后继续使用元素,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
生成器表达式的好处是它使用更少的内存,因为它不会一次构建整个列表。生成器表达式最好在列表作为中介时使用,例如对结果求和,或从结果中创建字典。
例如:
sum(x*2 for x in xrange(256))
dict( (k, some_func(k)) for k in some_list_of_keys )
这样做的好处是列表不是完全生成的,因此占用的内存很少(而且应该更快)。
但是,当期望的最终产品是一个列表时,应该使用列表推导式。使用生成器表达式不会节省任何内存,因为您需要生成的列表。您还可以使用任何列表函数,如sorted或reversed。
例如:
reversed( [x*2 for x in xrange(256)] )
当结果需要多次迭代时,或者在速度非常重要的情况下,使用列表推导式。在范围较大或无穷大的地方使用生成器表达式。
有关更多信息,请参阅生成器表达式和列表推导式。
Python 3.7:
列表推导更快。
生成器的内存效率更高。
正如其他人所说,如果你想要扩展无限的数据,你最终还是需要一个生成器。对于相对静态的、需要快速处理的中小型工作,最好是对清单进行理解。
列表推导式是热切的,但生成器是懒惰的。
在列表推导式中,所有对象都是立即创建的,它需要更长的时间来创建和返回列表。在生成器表达式中,对象创建被延迟到next()请求。在next()生成器对象创建并立即返回时。
在列表推导中迭代更快,因为已经创建了对象。
如果迭代列表解析和生成器表达式中的所有元素,时间性能大致相同。即使生成器表达式立即返回生成器对象,它也不会创建所有元素。每次迭代一个新元素时,它都会创建并返回它。
But if you do not iterate through all the elements generator are more efficient. Let's say you need to create a list comprehensions that contains millions of items but you are using only 10 of them. You still have to create millions of items. You are just wasting time for making millions of calculations to create millions of items to use only 10. Or if you are making millions of api requests but end up using only 10 of them. Since generator expressions are lazy, it does not make all the calculations or api calls unless it is requested. In this case using generator expressions will be more efficient.
在列表推导式中,整个集合被加载到内存中。但是生成器表达式,一旦它在下一次()调用时返回一个值给你,它就完成了,不需要再将它存储在内存中。只有一个项目被载入内存。如果你在磁盘上迭代一个巨大的文件,如果文件太大,你可能会遇到内存问题。在这种情况下,使用生成器表达式更有效。