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

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

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

当前回答

Python 3.7:

列表推导更快。

生成器的内存效率更高。

正如其他人所说,如果你想要扩展无限的数据,你最终还是需要一个生成器。对于相对静态的、需要快速处理的中小型工作,最好是对清单进行理解。

其他回答

Python 3.7:

列表推导更快。

生成器的内存效率更高。

正如其他人所说,如果你想要扩展无限的数据,你最终还是需要一个生成器。对于相对静态的、需要快速处理的中小型工作,最好是对清单进行理解。

对于函数式编程,我们希望使用尽可能少的索引。因此,如果我们想在获取元素的第一个切片后继续使用元素,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

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

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

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

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

当从一个可变对象(比如一个列表)创建一个生成器时,请注意生成器将在使用生成器时根据列表的状态进行计算,而不是在创建生成器时:

>>> mylist = ["a", "b", "c"]
>>> gen = (elem + "1" for elem in mylist)
>>> mylist.clear()
>>> for x in gen: print (x)
# nothing

如果你的列表有可能被修改(或者列表中的一个可变对象),但你需要生成器创建时的状态,你需要使用列表理解。