Python 迭代器:从入门到精通

在学 Python 的过程中,我们常常会碰到"迭代器"这个词。它听起来有点抽象,其实本质就是一种"能一个一个取值"的东西。本文就来系统讲讲迭代器,帮你把这个概念吃透。

参考文章:

目录

  1. 什么是可迭代对象(Iterable)?
  2. 什么是迭代器(Iterator)?
  3. iter()next() 的用法
  4. for 循环背后的迭代器机制
  5. 为什么需要迭代器?
  6. 自定义一个迭代器类
  7. 使用生成器简化迭代器
  8. isinstance() 判断是不是迭代器
  9. 可迭代但不是迭代器的对象
  10. 小结和注意事项

1. 什么是可迭代对象(Iterable)?

可迭代对象指的是能被一个个遍历的对象 ,比如列表、字符串、元组、集合、字典等等。判断一个对象是否可迭代,可以用 collections.abc.Iterable 来检查:

python 复制代码
from collections.abc import Iterable

print(isinstance([1, 2, 3], Iterable))  # True
print(isinstance(123, Iterable))       # False

这些对象可以用 for 循环,是因为它们都实现了 __iter__() 方法。


2. 什么是迭代器(Iterator)?

迭代器是一个可以记住当前遍历位置的对象 ,从它那里你可以不停地 next() 出下一个值,直到取不到为止(会抛出 StopIteration 异常)。

一个对象如果:

  • 实现了 __iter__() 方法,返回自身
  • 实现了 __next__() 方法

那它就是一个迭代器。

python 复制代码
from collections.abc import Iterator

print(isinstance(iter([1, 2, 3]), Iterator))  # True

3. iter()next() 的用法

Python 提供了两个内置函数和迭代器打交道:

  • iter(obj):把一个可迭代对象变成迭代器
  • next(iterator):从迭代器里取出下一个值

示例:

python 复制代码
nums = [10, 20, 30]
it = iter(nums)

print(next(it))  # 10
print(next(it))  # 20
print(next(it))  # 30
# print(next(it))  # 报错:StopIteration

4. for 循环背后的迭代器机制

你用惯的 for 循环,其实背后就是在用迭代器。来看下"真相":

python 复制代码
for x in [1, 2, 3]:
    print(x)

其实等价于:

python 复制代码
it = iter([1, 2, 3])
while True:
    try:
        x = next(it)
        print(x)
    except StopIteration:
        break

是不是瞬间明白了?


5. 为什么需要迭代器?

迭代器有两个大优点:

  • 惰性计算:只有在需要下一个值的时候才去计算,节省内存
  • 适合处理大型数据流:比如处理几百 GB 的日志文件时,就不能一次性全部加载到内存中,这时候迭代器就派上用场了

6. 自定义一个迭代器类

我们可以自定义一个类来模拟迭代器的行为,比如实现一个生成斐波那契数列的迭代器:

python 复制代码
class Fibonacci:
    def __init__(self, max):
        self.max = max
        self.a = 0
        self.b = 1

    def __iter__(self):
        return self

    def __next__(self):
        if self.a > self.max:
            raise StopIteration
        value = self.a
        self.a, self.b = self.b, self.a + self.b
        return value

fib = Fibonacci(100)
for num in fib:
    print(num, end=' ')

输出:0 1 1 2 3 5 8 13 21 34 55 89


7. 使用生成器简化迭代器

虽然可以用类实现迭代器,但有时候写起来太麻烦。Python 提供了更简洁的方式:生成器(generator)

yield 写个斐波那契生成器:

python 复制代码
def fibonacci(max):
    a, b = 0, 1
    while a <= max:
        yield a
        a, b = b, a + b

for n in fibonacci(100):
    print(n, end=' ')

是不是比类清爽多了?


8. isinstance() 判断是不是迭代器

快速判断对象的类型是否是可迭代或迭代器:

python 复制代码
from collections.abc import Iterable, Iterator

print(isinstance([1, 2, 3], Iterable))  # True
print(isinstance([1, 2, 3], Iterator))  # False

it = iter([1, 2, 3])
print(isinstance(it, Iterator))        # True

9. 可迭代但不是迭代器的对象

很多常见的结构(比如 list、str)是"可迭代的",但它们不是"迭代器":

python 复制代码
lst = [1, 2, 3]
print(hasattr(lst, '__iter__'))   # True
print(hasattr(lst, '__next__'))   # False

不过你可以随时把它变成迭代器:

python 复制代码
it = iter(lst)
print(next(it))  # 1

10. 小结

  • 所有能被 for 遍历的都是"可迭代对象"
  • 迭代器是"可迭代对象"的一种升级版,它支持 next()、惰性计算
  • 自定义迭代器要写 __iter__()__next__() 方法
  • 想省事就用生成器 yield,写起来又简洁又优雅
  • 一定要注意 StopIteration,它是控制"结束"的信号
相关推荐
飞鸟真人12 分钟前
关于python -m http.server的一些安全问题
python·安全·http
tjjucheng18 分钟前
小程序定制开发哪家性价比高
python
No0d1es29 分钟前
2025年12月 GESP CCF编程能力等级认证Python六级真题
python·青少年编程·gesp·ccf·六级
亮子AI1 小时前
【Python】比较两个cli库:Click vs Typer
开发语言·python
CappuccinoRose1 小时前
流计算概述
python·flink·流计算·数据流·pyflink
Dragon水魅1 小时前
Fandom Wiki 网站爬取文本信息踩坑实录
爬虫·python
Darkershadow1 小时前
蓝牙学习之unprovision beacon
python·学习·ble
小龙在山东1 小时前
基于 plumbum 跨平台执行Shell脚本
python
CCPC不拿奖不改名2 小时前
python基础:python语言中的函数与模块+面试习题
开发语言·python·面试·职场和发展·蓝桥杯
毕设源码-朱学姐2 小时前
【开题答辩全过程】以 基于Python语言的疫情数据可视化系统为例,包含答辩的问题和答案
开发语言·python·信息可视化