生成器是python非常有用的一项特性。若想了解生成器,需要首先了解迭代器。

  一、迭代器:便于较大数据的集合,节省内存

  可迭代对象是指:提供next方法(要么返回下一项、要么引发异常)的对象。

  迭代器是指满足迭代器协议,可以访问迭代对象的函数。如最常用的for循环,和sum、min、max等函数。

# list是可迭代对象,for访问list
list_ = [1,2,4]
for i in list:print(i)

# python文件满足迭代协议,提供next方法,是可迭代对象
# for 迭代访问python文件
with open('file.py') as f:
    for line in f:
        print(line)
View Code

  注意:迭代器访问迭代对象,只能从前向后顺序执行,不能回头。

  二、生成器:支持延迟操作,一次返回一个结果

  延迟操作:在需要的时候才产生结果,不是立即产生结果。

  python生成器有两种形式:生成器函数和生成器表达式。

  (一)生成器函数:使用yield替代return返回值,每次next执行一次函数到yield处,下一次next从上一次yield结束位置继续执行,知道迭代结束抛出异常。

  (二)生成器表达式:生成器表达式使用圆括号()代替中括号[]。

# 生成器函数,用yield代替return返回
# 生成器返回自然数的平方
def gensquares(N):
    for i in range(N):
        yield i*i
# 迭代器调用
for i in gensquares(5):
    print(i,end=' ')   # 0 1 4 9 16

# 生成器表达式
# 常规写法:
squares = [x**2 for x in range(5)]
print(type(squares))   # <class 'list'>
print(squares)         # [0, 1, 4, 9, 16]
# 生成器表达式写法:
squares = (x**2 for x in range(5))
print(type(squares))   # <class 'generator'>
print(squares)         # <generator object <genexpr> at 0x02189E40>
print(next(squares))   # 0
print(next(squares))   # 1
print(next(squares))   # 4
print(next(squares))    # 9
print(next(squares))    # 16
print(next(squares))     # StopIteration
View Code

  注意:生成器只能遍历一次,如果已经遍历过,之后将不再有结果返回。