在Python中什么时候应该使用生成器表达式,什么时候应该使用列表推导式?

# Generator expression
(x*2 for x in range(256))

# List comprehension
[x*2 for x in range(256)]

当前回答

有时候你可以在itertools中使用tee函数,它会为同一个生成器返回多个迭代器,这些迭代器可以独立使用。

其他回答

当结果需要多次迭代时,或者在速度非常重要的情况下,使用列表推导式。在范围较大或无穷大的地方使用生成器表达式。

有关更多信息,请参阅生成器表达式和列表推导式。

列表推导式是热切的,但生成器是懒惰的。

在列表推导式中,所有对象都是立即创建的,它需要更长的时间来创建和返回列表。在生成器表达式中,对象创建被延迟到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.

在列表推导式中,整个集合被加载到内存中。但是生成器表达式,一旦它在下一次()调用时返回一个值给你,它就完成了,不需要再将它存储在内存中。只有一个项目被载入内存。如果你在磁盘上迭代一个巨大的文件,如果文件太大,你可能会遇到内存问题。在这种情况下,使用生成器表达式更有效。

遍历生成器表达式或列表推导式也会做同样的事情。但是,列表推导式将首先在内存中创建整个列表,而生成器表达式将动态地创建项,因此您可以将其用于非常大的(也是无限的!)序列。

John的回答很好(当您想要多次迭代某个内容时,列表推导式更好)。然而,同样值得注意的是,如果您想使用任何列表方法,则应该使用列表。例如,下面的代码将无法工作:

def gen():
    return (something for something in get_some_stuff())

print gen()[:2]     # generators don't support indexing or slicing
print [5,6] + gen() # generators can't be added to lists

基本上,如果你所做的只是迭代一次,就使用生成器表达式。如果希望存储和使用生成的结果,那么最好使用列表推导式。

由于性能是最常见的选择一个而不是另一个的原因,我的建议是不要担心,只选择一个;如果您发现您的程序运行得太慢,那么只有在这时,您才应该返回并考虑调优您的代码。

有时候你可以在itertools中使用tee函数,它会为同一个生成器返回多个迭代器,这些迭代器可以独立使用。