Python List Comprehensions vs Generator Expressions
本文是译文,原文:
https://www.geeksforgeeks.org/python-list-comprehensions-vs-generator-expressions/
列表推导式与生成器表达式
什么是列表推导式
列表推导式是一种定义和创建列表的优雅方式。它让我们以更少的代码、使用for循环创建列表。使用列表推导式只需要一行代码,否则的话,一般需要3到4行代码。
例子(不使用列表推导式):
# initializing the list list = [] for i in range(11): if i % 2 == 0: list.append(i) # print elements print(list)
输出
0 2 4 6 8 10
现在让我们使用列表推导式:
list = [i for i in range(11) if i % 2 == 0] print(list)
输出
0 2 4 6 8 10
什么是生成器表达式
生成器表达式在某种程度上与列表推导式有类似地方,但是生成器表达式并不构建列表对象。与(列表推导式)创建一个列表并将整个序列存储在内存中不同,生成器只会在需要的时候,生成下一个元素。
对于一个有return语句的一般函数,当它被调用的时候,当执行到return语句时,就结束了。但是一个有yield语句的函数,会保存函数的状态,当下次调用的时候,它会从这个保存的状态继续执行。
生成器表达式允许我们在不使用yield关键字的情况下创建一个生成器。
语法区别:生成器表达式使用圆括号,而不像列表推导式使用方括号。
列表推导式:
# List Comprehension list_comprehension = [i for i in range(11) if i % 2 == 0] print(list_comprehension)
输出
0 2 4 6 8 10
生成器表达式:
# Generator Expression generator_expression = (i for i in range(11) if i % 2 == 0) print(generator_expression)
输出
<generator object at 0x000001452B1EEC50>
在上面的例子中,如果我们想打印生成器表达式的结果,我们可以遍历这个生成器表达式对象:
for i in generator_expression: print(i, end=" ")
输出
0 2 4 6 8 10
列表推导式与生成器表达式区别
生成器表达式只会在每次调用的时候,生成一个元素。相反,列表推导式需要存储所有元素。这样我们可以说,生成器表达式比列表更节约内存。
让我们看下下面的例子。
# import getsizeof from sys module from sys import getsizeof comp = [i for i in range(10000)] gen = (i for i in range(10000)) #gives size for list comprehension x = getsizeof(comp) print("x = ", x) #gives size for generator expression y = getsizeof(gen) print("y = ", y)
输出
x = 87624 y = 88
我们看到生成器表达式可以节约内存。那么执行效率上哪?我们看下下一个例子。
#List Comprehension: import timeit print(timeit.timeit('''list_com = [i for i in range(100) if i % 2 == 0]''', number=1000000))
输出
8.118047142050102
#Generator Expression: import timeit print(timeit.timeit('''gen_exp = (i for i in range(100) if i % 2 == 0)''', number=1000000))
输出
0.7548244756850693
在执行时间上二者差别显著。可见,生成器表达式更快,更高效。