迭代器,生成器,生成器表达式

迭代器(Iterator,教程9.9节)

前面简单介绍过迭代器的概念,并说明各种序列类型的对象可以作为迭代器使用。迭代器在 Python 程序里扮演了很重要的角色,其最重要用途包括为 for 语句中的循环变量提供一系列的值,为各种序列生成式的局部变量提供值,还有一些内置函数要求迭代器参数。程序员也可以根据特定的规则在任何合适的场合使用迭代器。

Python 允许程序员根据需要用类的方式自己定义 "迭代器类型",使这种类的每个实例对象是一个迭代器。一个迭代器对象要支持两个方法:

  • __iter__() 返回一个迭代器对象,它可以返回自身。
  • __next__() 返回下一个迭代值,在没有下一个值时 raise 一个 StopIteration 异常。
任何具有这个两个方法属性的对象都被看作是一个迭代器,例如,下面定义了一个简单的计数器迭代器类,最后是它的一个简单使用:
class CounterToN () :
    def __init__(self, final) :
        self.n = 0
        self.final = final
    def __iter__(self) :
        return self
    def __next__(self) :
        self.n += 1
        if (self.n > self.final):
            raise StopIteration
        return self.n

ct = CounterToN(10)
for i in ct :
    print(i * 5)

生成器(Generator,教程9.10节)

生成器是一种可以作为迭代器用的对象,采用函数定义的语法形式和 yield 语句,在函数的返回值的位置不写 return 语句而是写一个 yield 语句。这样定义的函数就不再是一个普通的函数,而是一个可以作为迭代器的生成器函数。调用这样的函数将得到一个生成器迭代器,可以用在任何需要迭代器的地方。

有关 yield 语句的细节见语言手册 7.7 节,简单情况下使用的形式是

yield 表达式列表
对生成器迭代器对象求下一个值(例如它出现在 for 语句头部)将导致其执行,执行达到 yield 语句时函数返回 yield "表达式列表" 的值(可以只是一个表达式),同时这个生成器对象也转入一种 "冻结" 状态,等待对它的下一次求值。

下面是一个简单的生成器函数,其功能类似于上面定义的迭代器类:

def countToN (n) :
    for i in range(1, n+1) :
        yield i

xx = countToN(10)
for i in xx :
	print(i*3)
上面第一个 for 之后的赋值语句创建一个生成器对象,并将其赋给变量 xx,随后的 for 语句里用这个生成器作为生成循环值的迭代器。

yield 表达式的形式与 yield 语句相同,但是作为表达式使用,有关情况见的语言手册 6.2.9 节。

生成器表达式(Generator Expression)

(参考教程 9.11 节,语言手册 6.2.8 节)

生成器表达式是一种类似于表(元组、字典)生成式的表达式,其语法形式是:

	( 生成式 )
对它求值将产生一个生成器对象。下面是两个例子:
(3*x for x in range(10))
(x * y + 5 for x in range(1, 10) for y in range(x, 10))
第一个表达式产生的生成器对象相当于 range(0, 30, 3),第二个表达式产生一个更复杂的生成器对象。

这种生成器表达式可以直接写在 for 语句头部等需要迭代器的地方。如

xxx = (x * y + 5 for x in range(1,10) for y in range(x, 10))
for i in xxx :
	print(i)
本页及相关页面(除另声明者外)由裘宗燕创建维护,可自由用于各种学习活动。其他使用需得到作者许可。