生成器

生成器

能以一种一致的方式对序列进行迭代(比如列表中的对象或文件中的行)是Python的一个重要特点。这是通过一种叫做迭代器协议(iterator protocol,它是一种使对象可迭代的通用方式)的方式实现的,一个原生的使对象可迭代的方法。比如说,对字典进行迭代可以得到其所有的键:

some_dict = {'a': 1, 'b': 2, 'c': 3}
 for key in some_dict:
     print(key)
a
b
c

当你编写for key in some_dict时,Python解释器首先会尝试从some_dict创建一个迭代器:

 dict_iterator = iter(some_dict)

 dict_iterator
 <dict_keyiterator at 0x7fbbd5a9f908>

迭代器是一种特殊对象,它可以在诸如for循环之类的上下文中向Python解释器输送对象。大部分能接受列表之类的对象的方法也都可以接受任何可迭代对象。比如min、max、sum等内置方法以及list、tuple等类型构造器:

 list(dict_iterator)
 ['a', 'b', 'c']

生成器(generator)是构造新的可迭代对象的一种简单方式。一般的函数执行之后只会返回单个值,而生成器则是以延迟的方式返回一个值序列,即每返回一个值之后暂停,直到下一个值被请求时再继续。要创建一个生成器,只需将函数中的return替换为yeild即可:

def squares(n=10):
    print('Generating squares from 1 to {0}'.format(n ** 2))
    for i in range(1, n + 1):
        yield i ** 2

调用该生成器时,没有任何代码会被立即执行:

 gen = squares()

 gen
 <generator object squares at 0x7fbbd5ab4570>

直到你从该生成器中请求元素时,它才会开始执行其代码:

for x in gen:
     print(x, end=' ')
Generating squares from 1 to 100
1 4 9 16 25 36 49 64 81 100

生成器表达式
另一种更简洁的构造生成器的方法是使用生成器表达式(generator expression)。这是一种类似于列表、字典、集合推导式的生成器。其创建方式为,把列表推导式两端的方括号改成圆括号:

 gen = (x ** 2 for x in range(100))
 gen
 <generator object <genexpr> at 0x7fbbd5ab29e8>

它跟下面这个冗长得多的生成器是完全等价的:

def _make_gen():
    for x in range(100):
        yield x ** 2
gen = _make_gen()

生成器表达式也可以取代列表推导式,作为函数参数:

 sum(x ** 2 for x in range(100))
 328350

 dict((i, i **2) for i in range(5))
 {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
上一篇:yield函数生成器


下一篇:es6中generator通俗理解