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,它是控制"结束"的信号
相关推荐
咖啡续命又一天4 分钟前
python 自动化采集 ChromeDriver 安装
开发语言·python·自动化
松果集1 小时前
【1】数据类型2
python
且慢.5891 小时前
命令行的学习使用技巧
python
海琴烟Sunshine1 小时前
leetcode 66.加一 python
python·算法·leetcode
罗橙7号2 小时前
【pyTorch】关于PyTorch的高级索引机制理解
人工智能·pytorch·python
B站计算机毕业设计之家2 小时前
智能监控项目:Python 多目标检测系统 目标检测 目标跟踪(YOLOv8+ByteTrack 监控/交通 源码+文档)✅
python·yolo·目标检测·目标跟踪·智慧交通·交通·多目标检测
江上月5132 小时前
django与vue3的对接流程详解(下)
后端·python·django
nightunderblackcat2 小时前
四大名著智能可视化推演平台
前端·网络·爬虫·python·状态模式
小蕾Java2 小时前
PyCharm入门级详细使用手册(Python新手快速上手篇)
ide·python·pycharm
动能小子ohhh2 小时前
AI智能体(Agent)大模型入门【9】--如何在pycharm等其他编译软件调用ocr工具【只写后端代码不演示】
人工智能·python·深度学习·机器学习·pycharm·ocr