迭代器和生成器
迭代器
什么是迭代呢?在编程中,迭代指的是通过重复执行某个操作,不断获取被迭代对象中的数据。这样的每一次操作就是就是一次迭代。
迭代器是具有迭代功能的对象。我们使用迭代器来进行迭代操作。
迭代器 = iter(容器)
>>> numbers=[1,2,3,4,5]
>>> it = iter(numbers)
>>> it
<listiterator object at 0x1007e6950>
>>>
for 循环的迭代过程
for 循环的迭代就是通过使用迭代器来完成的。它在背后所做的事情是:
- 对一个容器调用 iter() 函数,获取到该容器的迭代器
- 每次循环时对迭代器调用 next() 函数,以获取一个值
- 若捕获到 StopIteration 异常则结束循环
可迭代(Iterable)对象
并不是所有的对象都可以被 iter() 函数使用。
什么是可迭代(的)?
1、从表面来看,所有可用于 for 循环的对象是可迭代的,如列表、元组、字符串、集合、字典等容器
2、从深层来看,定义了 iter() 方法的类对象就是可迭代的。当这个类对象被 iter() 函数使用时,将返回一个迭代器对象。如果对象具有__iter__() 方法,则可以说它支持迭代协议。
判断一个已有的对象是否是可迭代的
1、 ‘iter’ in dir(list)
2、 isinstance(对象, Iterable)
自定义迭代器
class MyIterator:
def __next__(self):
代码块
def __iter__(self):
return self
生成器
刚才我们自定义了迭代器,其实创建迭代器还有另一种方式,就是使用生成器。
生成器是一个函数,这个函数的特殊之处在于它的 return 语句被 yield 语句替代。
def power_of_two():
for exponent in range(11): # range(11) 表示左闭右开区间 [0, 11),不包含 11
yield 2 ** exponent # 以 2 为底数求指数幂
生成器使用方法:
p = power_of_two() # 以函数调用的方式创建生成器对象
next(p) # 同样使用 next() 来取值
生成器的关键在于 yield 语句。yield 语句的作用和 return 语句有几分相似,都可以将结果返回。不同在于,生成器函数执行至 yield 语句,返回结果的同时记录下函数内的状态,下次执行这个生成器函数,将从上次退出的位置(yield 的下一句代码)继续执行。当生成器函数中的所有代码被执行完毕时,自动抛出 StopIteration 异常。
我们可以看到,生成器的用法和迭代器相似,都使用 next() 来进行迭代。这是因为生成器其实就是创建迭代器的便捷方法,生产器会在背后自动定义 iter() 和 next() 方法。
生成器表达式(Generator Expression)
可以用一种非常简便的方式来创建生成器,就是通过生成器表达式。生成器的写法非常简单,但是灵活性也有限,所能表达的内容相对简单。
生成器表达式的写法如下:
生成器 = (针对项的操作 for 项 in 可迭代对象)
>>> letters = (item for item in 'abc')
>>> letters
<generator object <genexpr> at 0x1007d4960>
>>> next(letters)
'a'
>>> next(letters)
'b'
>>>
列表生成式
[对项的操作 for 项 in 可迭代对象]