迭代器Iterator
实现了迭代器协议的对象,我们称之为迭代器对象。
所谓迭代器协议,要求对象实现了__iter__()
和next()
方法,调用__iter__()
方法会返回一个对象自身,调用next()
方法会返回下一个元素值。如果已经迭代完成,对象没有值可以返回,就会引发一个名称为StopIteration
的异常。
迭代器的使用举例:
1 | #!/usr/bin/python |
其中iter()
方法获取了list的迭代器对象。
自定义迭代器的举例:
1 | #!/usr/bin/python |
生成器
生成器是一种特殊的“迭代器”。生成器在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 | #!/usr/bin/python |
返回结果如下:
<type 'generator'>
42
Hello, Guys!!!
另外,除了上面使用生成器函数来构造生成器外,还可以使用生成器表达式来构造生成器,代码举例如下:
1 | squares = (x**2 for x in range(5)) #形如列表推导式,但是将中括号换成了小括号 |
备注:Python中可以使用生成器来实现Python协程编程。当然,还可以使用第三方的库来实现Python协程编程。