__iter__,它是迭代器协议的基础。
1. 迭代器协议
# 迭代(iterate)意味着重复多次,就像循环那样。之前只使用for循环迭代过序列和字典,
# 但实际上也可迭代其他对象:实现了方法__iter__的对象。
# 方法__iter__返回一个迭代器,它是包含方法__next__的对象,而调用这个方法时可不提供
# 任何参数。当你调用方法__next__时,迭代器应返回其下一个值。如果迭代器没有可供返回的值,
# 应引发StopIteration异常。你还可使用内置的便利函数next,在这种情况下,next(it)与
# it.__next__()等效。
# 注意 在Python 3中,迭代器协议有细微的变化。在以前的迭代器协议中,要求迭代器对象包含
# 方法next而不是__next__。
# 这有什么意义呢?为何不使用列表呢?因为在很多情况下,使用列表都有点像用大炮打蚊
# 子。例如,如果你有一个可逐个计算值的函数,你可能只想逐个地获取值,而不是使用列表一次
# 性获取。这是因为如果有很多值,列表可能占用太多的内存。但还有其他原因:使用迭代器更通
# 用、更简单、更优雅。下面来看一个不能使用列表的示例,因为如果使用,这个列表的长度必须
# 是无穷大的!
class Fibs:
def __init__(self):
self.a = 0
self.b = 1
def __next__(self):
self.a, self.b = self.b, self.a + self.b
return self.a
def __iter__(self):
return
注意到这个迭代器实现了方法_ _ iter _ _ ,而这个方法返回迭代器本身。在很多情况下,都在
另一个对象中实现返回迭代器的方法 _ _ iter _ _ ,并在for循环中使用这个对象。但推荐在迭代器
中也实现方法 _ _ iter _ _ (并像刚才那样让它返回self),这样迭代器就可直接用于for循环中。
注意 更正规的定义是,实现了方法 _ _ iter _ _ 的对象是可迭代的,而实现了方法 _ _ next _ _ 的对象是迭代器。
# 首先,创建一个Fibs对象。
fibs = Fibs()
# 然后就可在for循环中使用这个对象,如找出第一个大于1000的斐波那契数。
for f in fibs:
if f > 1000:
print(f) # 1597
break
#这个循环之所以会停止,是因为其中包含break语句;否则,这个for循环将没完没了地执行。
# 提示 通过对可迭代对象调用内置函数iter,可获得一个迭代器。
it = iter([1, 2, 3])
next(it) # 1
next(it) # 2
2、从迭代器创建序列
# 除了对迭代器和可迭代对象进行迭代(通常这样做)之外,还可将它们转换为序列。在可以
# 使用序列的情况下,大多也可使用迭代器或可迭代对象(诸如索引和切片等操作除外)。一个这
# 样的例子是使用构造函数list显式地将迭代器转换为列表。
class TestIterator:
def __init__(self):
self.value = 0
def __next__(self):
self.value += 1
if self.value > 10:
raise StopIteration
return self.value
def __iter__(self):
return self
ti = TestIterator()
print(list(ti))
3、通过迭代器遍历列表
list = [1, 2, 3, 4]
it = iter(list)
while True:
try:
num = next(it)
except StopIteration:
break
print(num)
4、通过迭代器一边遍历一边增加元素值
list = [1, 2, 3, 4]
it = iter(list)
while True:
try:
num = next(it)
if num % 2 == 0:
list.append(1)
except StopIteration:
break
print(num)