Python中迭代器和生成器总结

迭代器Iterator

实现了迭代器协议的对象,我们称之为迭代器对象。

所谓迭代器协议,要求对象实现了__iter__()next()方法,调用__iter__()方法会返回一个对象自身,调用next()方法会返回下一个元素值。如果已经迭代完成,对象没有值可以返回,就会引发一个名称为StopIteration的异常。

迭代器的使用举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/python

city = ['beijing', 'shanghai', 'tianjin', 'chongqing']
it = iter(city)

print type(it)

#方法一:使用for循环来使用迭代器
for x in it:
print x

#方法二:使用next方法来使用迭代器
print it.next()
print it.next()
print it.next()
print it.next()

其中iter()方法获取了list的迭代器对象。

自定义迭代器的举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/python

class MyRange(object):
def __init__(self, n):
self.idx = 0
self.n = n

def __iter__(self):
return self

def next(self):
if self.idx < self.n:
val = self.idx
self.idx += 1
return val
else:
raise StopIteration()

myRange = MyRange(3)
for elem in myRange:
print elem

生成器

生成器是一种特殊的“迭代器”。生成器在Python中的类型是<type 'generator'>

一个包含了yield关键字的函数就是一个生成器,该函数也叫生成器函数。当生成器函数被调用时,在函数体中的代码不会被执行,而会返回一个迭代器。每次请求一个值,就会执行生成器中代码,直到遇到一个yield表达式或return语句。yield表达式表示要生成一个值,return语句表示要停止生成器。

换句话说,生成器是由两部分组成,生成器的函数和生成器的迭代器。生成器的函数是用def语句定义的,包含yield部分。生成器的迭代器是这个函数返回的部分。二者合起来叫做生成器

几个需要注意的的点:

(1)调用生成器函数时,不会执行生成器函数的代码,而是直接返回一个迭代器iterator对象

(2)生成迭代器对象后,可以使用iterator_obj.next()或者iterator_obj.send(None)来执行,切记使用send函数第一次调用生成器时,参数必须是None,不然会抛出异常。

(3)yield xxx是表达式,不是Python语句。yield xxx会将xxx值返回给send或者next函数,即调用处。同时yield xxx表达式也有计算结果,计算结果即为send函数中的参数值。

生成器使用举例:

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/python

def repeater(value):
while True:
new = yield value
if new is not None: value = new

it = repeater(42)

print type(it)
print it.next() #亦可以使用print it.send(None)
print it.send('Hello, Guys!!!')

返回结果如下:

<type 'generator'>
42
Hello, Guys!!!

另外,除了上面使用生成器函数来构造生成器外,还可以使用生成器表达式来构造生成器,代码举例如下:

1
2
3
4
squares = (x**2 for x in range(5)) #形如列表推导式,但是将中括号换成了小括号

for square in squares:
print square

备注:Python中可以使用生成器来实现Python协程编程。当然,还可以使用第三方的库来实现Python协程编程。