Python生成器表达式与列表推导式
生成器
有点类似于列表推导式但并不生成列表对象。生成器是仅当被需要时才产生下一项,而不是像列表推导式一样,生成整个列表并存在内存中。一个有返回的正常函数被调用时,当调用方得到返回时调用结束。但有yield声明的函数保存了函数状态并且能在下一次函数被调用时,以相同状态被唤醒。生成器表达式允许我们无需yield即可创建生成器。
#传统的列表创建方式
list1 = []
for i in range(100):
if i % 3 == 0:
a.append(i)
print(a)
#列表推导式
list1 = [i for i in range(10) if i % 3 == 0]
#生成器表达式创建
generator1 = (i for i in range(100) if i % 3 == 0)
列表推导式和生成器表达式外观(语法)上的主要区别在于列表推导式用方括号,生成器表达式用圆括号。打印生成器表达式的创建结果,是该对象的存储地址。如果想打印生成器表达式的输出,可以遍历该生成器对象:
for i in generator1:
print(i, end = "")
列表推导式和生成器表达式的区别:
1、内存使用效率:
如下所示,生成器仅在需要时(被调用时)一次产生一项结果存入内存,然而在列表推导式中,Python为整个列表保留内存。可以说,生成器表达式相比于列表在内存使用效率上更高。
from sys import getsizeof
a = [i for i in range(99999)]
b = (i for i in range(99999))
x = getsizeof(a)
y = getsizeof(b)
print(x)
824464
print(y)
88
2、时间效率:
如下所示,在执行时间上,列表推导式和生成器表达式在执行时间上也有很明显的差别,因此,生成器表达式比列表推导式更快,更节约时间。
import timeit
# 列表推导式
print(timeit.timeit('''list_com = [i for i in range(100) if i % 3 == 0]''',number = 10000000)
# 生成器表达式
print(timeit.timeit('''gen_exp = (i for i in range(100) if i % 3 == 0)''',number = 10000000)
# 列表推导式输出:
4.669294930994511
#生成器表达式输出:
0.4217875720351003