对于python中两种延迟生成值的结构:
- 生成器函数
- 生成器表达式
我相信生成器函数各位都是不陌生的,就是在函数返回值前用yield,但是注意一点,这里我并没有说用yield代替return,两个意义其实是不同的,所以不存在代替的问题,两者可以共存。
例如:
def instance():
for i in range(1, 6):
yield i
if i == 4:
return "over"
所以两者共存没有牟盾。
当然利用关键字yield创建的函数是一个生成器,每次调用都会返回一个值。
同样,生成器表达式也是一个节省内存空间的方法
其一般格式如下:
generator = (x for x in range(1, 8))
如上就是一个生成器表达式,重点强调的是,生成器函数和生成器表达式本身就是一个迭代器。
那么为什么说两者可以节省内存空间呢?
如下的对比的例子
生成器函数:
def generator():
for i in range(1, 19):
yield i
每次调用是返回一个值,而不是将所有的值一次性返回,其调用可以在任何的迭代工具中,如:
for i in generator():
print(i)
或者:
x = generator()
# 产生一个生辰器函数实例
while True:
print(next(x))
# 知道引发一个StopIteration错误
而相同效果的普通函数,如:
def ordinary():
return [i for in range(1, 19)]
会一次性在内存中生成这个列表,从而加重的内存的负担,这种在比较大的结构中影响更加明显。
对于我们的生成器表达式,它和列表解析有些相似之处。
生成器表达式:
generator = (x for x in range(1, 19))
同样我们可以在任何的迭代工具中使用这个生成器(本身是迭代器)
相似结构的列表解析,如:
list = [x for x in range(1, 19)]
同样,我们的列表解析生成了一个完整的列表,所以在数据较多时使用生成器表达式还是好的
重要的是,其实在数据较少时,使用列表解析更快,所以选哪个这里考虑!