Python 迭代器:不是循环本身,而是让循环更优雅的工具

这篇文章将帮助你理解:

  • 什么是迭代器(Iterator)

  • 它和我们常用的for 循环、列表有什么区别

  • 为什么说它在处理大数据或惰性求值时更有优势?

  • 如何自己实现一个迭代器?


一、先来回忆一下:我们平时是怎么“遍历数据”的?

我们在写代码的时候,经常会遇到这样的需求:

“我要依次访问一组数据中的每一个元素。”

比如:

fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

这段代码看起来很自然。但你知道吗?其实背后有一个非常重要的机制在起作用——这就是我们今天要讲的主角:迭代器(Iterator)


二、那么问题来了:迭代器到底是什么?

✅ 简单一句话总结:

迭代器是一个对象,它可以记住遍历的位置,并能一步步返回下一个元素。

你可以把它想象成一个“翻页器”:

  • 每次调用 .next()next(),它就会给你下一页内容;

  • 如果没有更多内容了,它就会抛出一个 StopIteration 异常。


✅ 和可迭代对象(Iterable)的区别

名称 中文名 特点
Iterable 可迭代对象 能被 for 遍历的对象,如列表、字符串、字典等
Iterator 迭代器 是一个实现了 .__iter__().__next__() 的对象

关键点:

所有迭代器都是可迭代对象,但不是所有可迭代对象都是迭代器。

举个例子:

nums = [1, 2, 3]  # 列表是可迭代对象
it = iter(nums)   # iter() 返回一个迭代器

三、迭代器的工作原理:它是怎么一步步取数据的?

我们来看一个手动使用迭代器的例子:

fruits = ["apple", "banana", "cherry"]
it = iter(fruits)
print(next(it))  # apple
print(next(it))  # banana
print(next(it))  # cherry
print(next(it))  # 抛出 StopIteration 异常
 这就是迭代器的本质:
  • 一次只返回一个元素;

  • 记住当前位置;

  • 数据用完后自动停止。


四、为什么我们要用迭代器?它比普通循环好在哪?

✅ 场景1:节省内存,适合处理大文件或无限数据

假设你要读取一个超大的日志文件,几GB大小。如果你一次性读入内存,电脑可能直接崩溃。

但如果使用迭代器,就可以一行一行地读取,而不是一次性加载全部内容。

with open("huge_log_file.log") as f:
    for line in f:  # f 是一个迭代器
        process(line)  # 逐行处理,不占内存

类比理解:就像看书一样,一页一页看,而不是把整本书拍到脸上。


✅ 场景2:支持“惰性求值”(Lazy Evaluation)

有些数据你并不需要一开始就计算出来,而是按需生成。这在函数式编程中非常常见。

例如,我们可以用迭代器实现一个“无限序列”:

import itertools
counter = itertools.count(start=1, step=1)  # 无限计数器for i in counter:
    if i > 10:
        break
    print(i)

输出:

123...10

关键点:这个迭代器并不会真正存储所有数字,而是在你需要时才“生成”它们。


五、如何自定义一个迭代器?

Python 允许我们通过定义类的方式,创建自己的迭代器。只需满足两个条件:

  1. 实现 __iter__() 方法;

  2. 实现 __next__() 方法。

示例:实现一个从 1 到 N 的计数器迭代器

class MyCounter:
    def __init__(self, start=1, end=10):
        self.current = start
        self.end = end

    def __iter__(self):
        return self

    def __next__(self):
        if self.current > self.end:
            raise StopIteration
        else:
            value = self.current
            self.current += 1
            return value

# 使用自定义迭代器
counter = MyCounter()  #注意,不能用counter = MyCounter(1,5),否则不会走自定义 
for num in counter:
    print(num)

输出:

12345

总结

  • 自定义迭代器让你拥有对“遍历逻辑”的完全控制;

  • 它非常适合用于封装复杂的遍历规则或数据流。


六、迭代器 vs 生成器:它们有什么关系?

对比项 迭代器 生成器
创建方式 类 + 实现 __iter____next__ 函数 + yield
内存占用 更灵活 更简洁
适用场景 复杂控制逻辑 快速构建惰性序列

举个生成器的例子:

def my_generator():
    yield 1
    yield 2
    yield 3

g = my_generator()
for x in g:
    print(x)

输出:

123

生成器本质上也是一个迭代器,但它更简洁、更易用。


七、一句话总结

迭代器不是一个循环,而是一种“按需提供数据”的机制。
它让我们的程序更高效、更灵活,尤其适合处理大数据、流式数据或无限序列。


八、常见误区澄清

说法 正确理解
所有 for 循环都用了迭代器? ✅ 是的,因为 for 内部会调用 iter()
列表是迭代器? ❌ 不是,列表是可迭代对象,不是迭代器
迭代器只能用一次? ✅ 是的,一旦遍历完成,必须重新获取一个新的迭代器
生成器不是迭代器? ❌ 错,生成器是特殊的迭代器

九、延伸阅读建议

如果你想进一步深入学习:

  • 学习 itertools 标准库,掌握强大的迭代工具;

  • 探索生成器表达式与列表推导式的区别;

  • 了解协程(coroutine)与生成器的关系;

  • 理解迭代器在异步编程(async/await)中的应用。


推荐阅读资源

  • 书籍:
    • 《流畅的 Python》(Luciano Ramalho)

    • 《Python 编程:从入门到实践》

  • 工具:
    • Python 官方文档(docs.python.org)

  • 实战项目:
    • 用迭代器读取大文件并统计词频

    • 实现一个“网页爬虫”,逐页抓取数据并处理

你可能感兴趣的:(08,python,python,职场发展,笔记,深度学习,人工智能,机器学习)