当前位置: 首页 > news >正文

【Python】迭代器与生成器详解(可迭代对象、定义、实现方式、区别、使用场景)

文章目录

  • 1. 可迭代对象
    • 1.1 常见的可迭代对象
    • 1.2 迭代器和生成器
  • 2. 迭代器
    • 2.1 定义
    • 2.2 原理
    • 2.3 特点
    • 2.4 示例
      • 2.4.1 for语句进行遍历
      • 2.4.2 next() 函数进行遍历
      • 2.4.3 自定义迭代器
    • 2.5 内置迭代器
  • 3. 生成器
    • 3.1 定义
    • 3.2 创建方式
      • 3.2.1 生成器表达式
      • 3.2.2 生成器函数
    • 3.3 特点
  • 4. 迭代器和生成器比较
    • 4.1 迭代器优势
    • 4.2 生成器优势
    • 4.2.1 惰性计算
    • 4.2.2 无限序列
    • 4.2.3 协程与状态管理
  • 5. 使用场景
    • 5.1 迭代器和生成器选择原则

1. 可迭代对象

  • 迭代是 Python 最强大的功能之一,是访问集合元素的一种方式
  • 可迭代对象 :可以被循环遍历的对象

1.1 常见的可迭代对象

  • 序列类型
    列表(list) :是一种可变的序列类型
    元组(tuple) :是一种不可变的序列类型
    字符串(str) :由字符组成的不可变序列
  • 集合类型
    集合(set) :无序且元素唯一的集合类型
    字典(dict) :以键 - 值对形式存储数据的集合类型。在遍历字典时,默认遍历的是键
  • 其他可迭代对象
    文件对象 :在 Python 中,打开的文件对象是可迭代的,可以逐行读取文件内容
    range() 对象 :用于生成一个不可变的整数序列

1.2 迭代器和生成器

在 Python 中,迭代器(Iterator) 和 生成器(Generator) 都是用于遍历数据的工具,用于处理可迭代对象

2. 迭代器

2.1 定义

迭代器是实现了迭代器协议的对象,是一个可以记住遍历位置的对象
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退
迭代器协议要求对象必须实现两个方法:iter() 和 next()

  • iter() :返回迭代器对象本身,通常返回 self。
  • next() :返回迭代器的下一个值,如果没有元素则抛出 StopIteration 异常

2.2 原理

迭代器是一种 惰性求值 的机制,它并不一次性生成所有元素,而是在需要时 逐个生成元素 ,这样可以节省内存
当你使用 for 循环遍历一个迭代器时,实际上是在不断调用迭代器的 next() 方法,直到抛出 StopIteration 异常

2.3 特点

  • 惰性计算 :按需生成元素,适合处理大数据集
  • 一次性使用 :遍历结束后需重新初始化才能再次使用
  • 手动控制 :需显式调用 next() 或使用 for 循环

2.4 示例

2.4.1 for语句进行遍历

迭代器对象使用常规 for语句 进行遍历

list = [1, 2, 3, 4]
it = iter(list)  # 创建迭代器对象
for x in it:
    print(x, end=" ")

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
1 2 3 4

Process finished with exit code 0

2.4.2 next() 函数进行遍历

也可以使用 next() 函数 进行遍历

import sys  # 引入 sys 模块

list = [1, 2, 3, 4]
it = iter(list)  # 创建迭代器对象

while True:
    try:
        print(next(it))
    except StopIteration:
        sys.exit()

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
1 2 3 4

Process finished with exit code 0

2.4.3 自定义迭代器

示例:生成 0 到 n 的偶数

class TestIterator:
    def __init__(self, n):
        self.n = n
        self.current = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.current >= self.n:
            raise StopIteration
        value = self.current
        self.current += 2
        return value

# 使用迭代器
even_iter = TestIterator(6)
for num in even_iter:
    print(num)  # 输出: 0 2 4

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
0 2 4

Process finished with exit code 0

注:
StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况;在 next() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代

2.5 内置迭代器

  • Python 中的许多内置对象(如列表、元组、字符串等)都可以通过 iter() 函数 转换为迭代器
my_list = [1, 2, 3, 4, 5]
my_iterator = iter(my_list)
print(next(my_iterator))  # 输出: 1
print(next(my_iterator))  # 输出: 2

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
1 2

Process finished with exit code 0

3. 生成器

3.1 定义

  • 生成器是一种特殊的迭代器,通过 yield 关键字 实现,无需显式定义 iternext

3.2 创建方式

3.2.1 生成器表达式

  • 生成器表达式:类似于列表推导式,但使用 圆括号 () 而不是方括号 []
gen_expr = (x for x in range(0, 6, 2))
print(list(gen_expr))  # 输出: [0, 2, 4]

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
[0, 2, 4]

Process finished with exit code 0

3.2.2 生成器函数

  • 生成器函数: 使用 def 定义,包含 yield 关键字 的函数
  • 当函数被调用时,它不会立即执行,而是返回一个生成器对象
  • 每次调用生成器的 next() 方法时,函数会从上次暂停的位置继续执行,直到遇到下一个 yield 语句或函数结束
# 生成器函数:生成 0 到 n 的偶数
def test_generator(n):
    current = 0
    while current < n:
        yield current
        current += 2
# 使用生成器
gen = test_generator(6)
for num in gen:
    print(num)  # 输出: 0 2 4
# test_generator 是一个生成器函数,yield 关键字将函数转换为生成器。
# 每次调用 __next__() 方法时,函数会执行到 yield 语句,返回 yield 后面的值,并暂停执行,下次调用时从暂停的位置继续执行

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
0 2 4

Process finished with exit code 0

3.3 特点

  • 简洁性 :自动实现迭代器协议,代码更简洁
  • 惰性计算 :按需生成元素,节省内存
  • 状态保存 :每次 yield 暂停执行,下次从暂停位置继续

4. 迭代器和生成器比较

\迭代器生成器
实现方式需手动定义 iternext使用 yield 或生成器表达式
代码复杂度代码较多代码更简洁
内存占用通常需预先生成数据惰性生成,节省内存
适用场景需要自定义复杂遍历逻辑快速实现按需生成数据
性能取决于实现逻辑通常更高(惰性计算优化)

4.1 迭代器优势

  • 需要 完全控制迭代逻辑 (如自定义遍历顺序)
  • 需要 复用迭代器对象 (生成器通常只能遍历一次)
# 自定义树结构的遍历
class TreeNode:
    def __init__(self, value):
        self.value = value
        self.children = []

class TreeIterator:
    def __init__(self, root):
        self.stack = [root]

    def __iter__(self):
        return self

    def __next__(self):
        if not self.stack:
            raise StopIteration
        node = self.stack.pop()
        self.stack.extend(node.children[::-1])  # 逆序压栈,实现前序遍历
        return node.value

# 使用迭代器遍历树
root = TreeNode(1)
root.children = [TreeNode(2), TreeNode(3)]
for value in TreeIterator(root):
    print(value)  # 输出: 1 2 3

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
1 2 3

Process finished with exit code 0

4.2 生成器优势

4.2.1 惰性计算

  • 按需生成:适用于处理 大文件或无限序列
  • 逐行读取大文件, 避免一次性加载到内存
def read_large_file(file_path):
    with open(file_path, "r") as file:
        for line in file:
            yield line.strip()

# 逐行处理文件
for line in read_large_file("data.txt"):
    process(line)  # 假设 process 是处理函数

4.2.2 无限序列

  • 生成器可以表示无限序列,如斐波那契数列
# 使用生成器函数生成斐波那契数列,并将该数列的前 n(这里 n 为 10)项依次打印输出
# !/usr/bin/python3
import sys

def fibonacci(n):  # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0 # 初始化三个变量
    while True:
        if (counter > n):
            return
        yield a
        a, b = b, a + b
        counter += 1

f = fibonacci(10)  # f 是一个迭代器,由生成器返回生成

while True:
    try:
        print(next(f), end=" ")
    except StopIteration:
        sys.exit()

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
0 1 1 2 3 5 8 13 21 34 55

Process finished with exit code 0

4.2.3 协程与状态管理

  • 生成器可通过 接收外部数据 send() ,用于协程编程
def coroutine():
    while True:
        received = yield
        print(f"Received: {received}")

co = coroutine()
next(co)       # 启动生成器
co.send("Hello")  # 输出: Received: Hello

输出:

D:\PycharmProjects\pythonProject.venv\Scripts\python.exe
D:\PycharmProjects\pythonProject-test.py
Received: Hello

Process finished with exit code 0

5. 使用场景

  • 大数据处理 send():当处理大型数据集时,使用迭代器和生成器可以避免一次性将所有数据加载到内存中,提高程序的性能和内存使用效率
  • 无限序列生成 send():生成器可以方便地生成无限序列,如斐波那契数列等,只需在生成器函数中使用循环和 yield 语句即可

5.1 迭代器和生成器选择原则

迭代器:适合需要精细控制遍历逻辑的场景,需手动实现接口
生成器:适合快速实现惰性计算、处理大数据或无限序列,代码简洁高效
选择原则

  • 优先使用生成器(更简洁,适合大多数场景)
  • 需要复杂遍历逻辑或复用迭代器时,使用迭代器

如有其他问题,欢迎各位大佬指正~

相关文章:

  • ROS 2机器人开发--第一个节点
  • 数据中心储能蓄电池状态监测管理系统 组成架构介绍
  • 网络协议相关知识有哪些?
  • linux进程的内存空间映射(段)
  • Spring Boot 常用注解详解
  • 宠物行业研究系列报告
  • 在大数据分析中如何选择合适的算法和模型
  • 黑马点评—短信登陆商户查询缓存
  • C++:使用 SFML 创建强化学习迷宫场景
  • JAVA EE初阶 JVM
  • nginx作为下载服务器配置
  • FPGA开发要学些什么?如何快速入门?
  • 第8章作业
  • Nginx知识详解(理论+实战更易懂)
  • 【十一】Golang 指针
  • 免费开源多平台轻量级本地视频工具,支持Windows、Android
  • 面试知识点2
  • Android 11.0 WiFi连接默认设置静态IP地址功能实现
  • mapbox基础,使用geojson加载Fill面图层
  • 2.20学习
  • 华尔兹转岗与鲁比奥集权:特朗普政府人事震荡背后的深层危机
  • 韩国法院将重审李在明案,韩德洙入局能否为大选带来变数?
  • 首开股份:一季度净利润亏损约10.79亿元,签约金额63.9亿元
  • 山西太原小区爆炸事故已造成17人受伤
  • 国台办:相关优化离境退税政策适用于来大陆的台湾同胞
  • 习近平访问金砖国家新开发银行