跳到主要内容

迭代器

1. 可迭代对象(Iterable)

  • 可直接作用于 for 循环的对象有两类:
    • 集合数据类型:list、tuple、dict、set、str 等;
    • generator:生成器、带 yield 的 generator 函数。
  • 这些对象统称为可迭代对象(Iterable)

判断是否 Iterable

from collections.abc import Iterable

isinstance([], Iterable) # True
isinstance({}, Iterable) # True
isinstance('abc', Iterable) # True
isinstance((x for x in range(10)), Iterable) # True
isinstance(100, Iterable) # False

2. 迭代器(Iterator)

  • 生成器除可用于 for 外,还可被 next() 不断调用并返回下一个值,直到抛出 StopIteration
  • 能被 next() 调用并不断返回下一个值的对象称为迭代器(Iterator)

判断是否 Iterator

from collections.abc import Iterator

isinstance((x for x in range(10)), Iterator) # True,生成器是 Iterator
isinstance([], Iterator) # False
isinstance({}, Iterator) # False
isinstance('abc', Iterator) # False
  • list、dict、str 是 Iterable,但不是 Iterator生成器既是 Iterable 也是 Iterator

3. iter():把 Iterable 变成 Iterator

  • 使用 iter() 可将 list、dict、str 等 Iterable 转成 Iterator
isinstance(iter([]), Iterator)    # True
isinstance(iter('abc'), Iterator) # True

4. 为什么 list、dict、str 不是 Iterator?

  • Iterator 表示的是一个数据流:可被 next() 不断返回下一个数据,直到没有数据时抛出 StopIteration。
  • 可把数据流看作有序序列,但不能提前知道长度,只能通过 next() 按需计算下一个数据。
  • 因此 Iterator 是惰性计算的:只有在需要下一个值时才计算。
  • Iterator 甚至可以表示无限数据流(如全体自然数),而 list 无法存储无限序列。

5. for 循环的本质

  • Python 的 for 循环本质上就是:先得到 Iterator,再不断调用 next(),遇到 StopIteration 就退出。
for x in [1, 2, 3, 4, 5]:
pass

等价于:

it = iter([1, 2, 3, 4, 5])   # 先获得 Iterator
while True:
try:
x = next(it)
except StopIteration:
break

小结

概念说明
Iterable可作用于 for 的对象;list、dict、str、generator 等
Iterator可作用于 next()、表示惰性序列的对象;生成器是 Iterator
关系list/dict/str 是 Iterable 不是 Iterator;可用 iter() 得到 Iterator
for 本质iter() 得到 Iterator → 循环 next() → 遇 StopIteration 退出

记忆:能 for 的是 Iterable;能 next() 的是 Iterator;for 内部就是 iter + next。