目录

一、迭代器

1、迭代器的基本概念

2、迭代器的实现方式

3、迭代器的典型应用场景

二、生成器

1、生成器的基本概念

2、生成器的实现方式

3、生成器的典型应用场景

4、读取大文件

三、迭代器与生成器的核心区别


前言

        在 Python 开发中,我们经常和 “遍历” 打交道 —— 从列表里取数据、从文件里读内容、从数据库里捞记录。迭代器和生成器就是帮我们高效做这件事的 “工具人”。但很多人总把它俩搞混:有人觉得生成器就是迭代器,有人用迭代器时总担心内存爆炸,有人写生成器时不知道 yield 到底咋用。​


一、迭代器

1、迭代器的基本概念

        在 Python 中,迭代器(Iterator) 是一种可以记住遍历位置的对象。它必须实现两个方法:

  • __iter__():返回迭代器对象本身;

  • __next__():返回容器中的下一个元素,如果没有更多元素则抛出 StopIteration 异常。

所有可迭代对象(如列表、元组、字典等)都可以通过 iter() 函数转换为迭代器。

示例:获取并使用内置迭代器

my_list = [10, 20, 30]

it = iter(my_list)

print(next(it))  # 输出: 10

print(next(it))  # 输出: 20

print(next(it))  # 输出: 30

# print(next(it))  # 抛出 StopIteration

2、迭代器的实现方式

        我们可以通过自定义类来手动实现一个迭代器,只需要实现 __iter__()__next__() 方法即可。

示例:实现一个数字范围迭代器

class MyRange:
    def __init__(self, start, end):
        self.current = start
        self.end = end

    def __iter__(self):
        return self

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

# 使用自定义迭代器
for i in MyRange(1, 5):
    print(i)
# 输出:
# 1
# 2
# 3
# 4

3、迭代器的典型应用场景

  • 遍历集合数据结构(如列表、元组、字典);

  • 实现自定义的数据访问逻辑;

  • 在需要精细控制遍历过程时使用;

  • 作为某些标准库函数或框架的接口规范;

示例:模拟数据库查询结果迭代器

        假设我们有一个模拟的数据库查询结果,希望以迭代器的方式一行一行返回数据。

class DBResultIterator:
    def __init__(self, data):
        self.data = data
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index < len(self.data):
            result = self.data[self.index]
            self.index += 1
            return result
        else:
            raise StopIteration

# 模拟数据库查询结果
data = [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}, {"id": 3, "name": "Charlie"}]
db_iter = DBResultIterator(data)

for row in db_iter:
    print(row)

输出:

{'id': 1, 'name': 'Alice'}
{'id': 2, 'name': 'Bob'}
{'id': 3, 'name': 'Charlie'}

二、生成器

1、生成器的基本概念

        生成器(Generator) 是一种特殊的迭代器,它通过函数配合 yield 关键字实现。每次调用 next() 时,生成器会从上次暂停的地方继续执行。生成器的最大优势是 惰性求值 ,即只在需要的时候才生成值,节省内存资源。

示例:简单的生成器函数

def my_generator():
    yield "Hello"
    yield "World"
    yield "!"

gen = my_generator()
print(next(gen))  # 输出: Hello
print(next(gen))  # 输出: World
print(next(gen))  # 输出: !

2、生成器的实现方式

        生成器有两种常见实现方式:

  1. 生成器函数(带 yield 的函数)

  2. 生成器表达式(类似列表推导式,但使用圆括号)

示例一:生成器函数 —— 斐波那契数列

def fibonacci(n):
    a, b = 0, 1
    while a < n:
        yield a
        a, b = b, a + b

# 使用生成器
for num in fibonacci(100):
    print(num)

示例二:生成器表达式

squares_gen = (x * x for x in range(5))
print(next(squares_gen))  # 输出: 0
print(next(squares_gen))  # 输出: 1
print(next(squares_gen))  # 输出: 4

3、生成器的典型应用场景

  • 处理大数据流或无限序列;

  • 延迟加载数据,提升性能;

  • 构建简洁高效的迭代逻辑;

  • 实现协程或异步编程的基础组件;

示例:模拟传感器数据流

        在物联网或 实时监控 系统中,我们可能需要不断获取传感器数据。由于这些数据是持续产生的,使用生成器非常适合。

import random
import time

def sensor_data_stream():
    while True:
        yield random.randint(20, 30)  # 模拟温度数据
        time.sleep(1)  # 每秒产生一次数据

# 使用生成器模拟实时数据流
for temp in sensor_data_stream():
    print(f"当前温度: {temp}°C")

4、读取大文件

        当处理非常大的日志文件时,一次性读入内存会导致程序崩溃,这时生成器就派上用场了!

示例:用生成器逐行读取文件

def read_large_file(file_path):

    with open(file_path, 'r', encoding='utf-8') as f:

        for line in f:
            yield line.strip()

# 使用生成器逐行处理
for line in read_large_file('big_log.txt'):
    print(line)  # 或者进行其他处理

三、迭代器与生成器的核心区别

特性 迭代器 生成器

实现方式

类中定义 __iter__() __next__()

使用 yield 生成器表达式

状态维护

手动维护状态

自动保存执行状态

可重用性

一般不可重置

不可重置,除非重新创建

编写难度

较复杂

更加简洁

内存占用

占用常规内存

惰性计算,节省内存

  • 迭代器是 “手动挡”:需要自己控制状态和迭代逻辑,适合自定义容器。​

  • 生成器是 “自动挡”:用 yield 自动处理迭代,代码更简洁,适合大数据和动态序列。

总结:

        迭代器和生成器就像是两种不同的工具,各有各的用途。迭代器适合做精细控制,而生成器则是“懒人福音”,尤其是在处理大数据时特别省心。不管是迭代器还是生成器,核心都是 “惰性计算” 和 “高效遍历”。

Logo

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。

更多推荐