Python案例怎么使用迭代器遍历?

wen python案例 11

本文目录导读:

Python案例怎么使用迭代器遍历?

  1. 目录导读
  2. 迭代器基础概念
  3. Python迭代器协议:底层机制剖析
  4. 遍历常用数据结构的实际案例
  5. 自定义迭代器案例:斐波那契数列生成器
  6. 生成器:更优雅的迭代器实现
  7. 实际场景应用:迭代器如何解决真问题?
  8. 性能对比与最佳实践

Python迭代器遍历实战:从基础语法到高级案例的完整指南

目录导读

  1. 迭代器基础概念 – 什么是迭代器?为什么需要它?
  2. Python迭代器协议__iter__()__next__() 的底层机制
  3. 遍历常用数据结构 – 列表、字典、文件的行级遍历
  4. 自定义迭代器案例 – 用类实现斐波那契数列生成器
  5. 生成器简化迭代yield 关键字的魔力
  6. 实际场景应用 – 大文件拆分、实时数据流处理
  7. 性能对比与最佳实践 – 迭代器 vs 列表推导式 vs 循环

迭代器基础概念

Q:迭代器(Iterator)和可迭代对象(Iterable)有什么区别?
A:可迭代对象是实现了 __iter__() 方法的对象(如列表、元组、字典),而迭代器是实现了 __iter__()__next__() 的对象,迭代器可以通过 next() 逐个返回元素,直到抛出 StopIteration 异常。

核心点:迭代器的本质是“惰性求值”——只在需要时产生下一个值,不一次性加载所有数据到内存,这对处理大文件、无限序列(如斐波那契数列)至关重要。

Python迭代器协议:底层机制剖析

Python中任何对象,只要实现了以下两个方法,就是迭代器:

  • __iter__():返回迭代器自身(通常返回 self)。
  • __next__():返回下一个可用的元素;如果没有更多元素,则抛出 StopIteration

示例:手动模拟列表遍历

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

注意for 循环底层就是自动调用 iter()next(),并捕获 StopIteration 异常。

遍历常用数据结构的实际案例

1 列表遍历

fruits = ['apple', 'banana', 'cherry']
for fruit in fruits:
    print(fruit.upper())

输出:APPLE BANANA CHERRY

2 字典遍历(键、值、键值对)

student_scores = {'Alice': 95, 'Bob': 87, 'Charlie': 92}
for name, score in student_scores.items():
    print(f'{name}: {score}')

3 文件行级遍历(处理大文件核心方法)

with open('large_log.txt', 'r') as file:
    for line in file:   # file 本身是可迭代对象
        if 'ERROR' in line:
            print(line.strip())

说明:文件对象实现的是行级迭代器,逐行读取内存,适合处理GB级日志文件。

自定义迭代器案例:斐波那契数列生成器

需求:生成前 N 个斐波那契数,但不预先生成整个列表(避免内存爆炸)。

class FibonacciIterator:
    def __init__(self, max_count):
        self.max_count = max_count
        self.count = 0
        self.a, self.b = 0, 1
    def __iter__(self):
        return self
    def __next__(self):
        if self.count >= self.max_count:
            raise StopIteration
        self.count += 1
        self.a, self.b = self.b, self.a + self.b
        return self.a
# 使用
fib = FibonacciIterator(10)
for num in fib:
    print(num, end=' ')  # 输出:1 1 2 3 5 8 13 21 34 55

Q:为什么不直接用列表存储?
A:如果只关心前几个值,列表浪费内存,迭代器只存储当前状态(a, b, count),适合无限序列或超长序列。

生成器:更优雅的迭代器实现

生成器是用 yield 关键字的函数,Python自动创建迭代器对象,无需手动实现 __iter____next__

生成器版斐波那契

def fibonacci_gen(max_count):
    a, b = 0, 1
    for _ in range(max_count):
        a, b = b, a + b
        yield a
for num in fibonacci_gen(10):
    print(num, end=' ')  # 输出相同结果

优点:代码更简洁,状态自动保存。yield 每次暂停函数,下次从暂停处继续。

实际案例:分块读取大文件

def read_in_chunks(file_path, chunk_size=1024):
    with open(file_path, 'rb') as f:
        while True:
            chunk = f.read(chunk_size)
            if not chunk:
                break
            yield chunk
# 使用
for chunk in read_in_chunks('big_video.mp4'):
    process_chunk(chunk)  # 模拟处理每1KB数据

实际场景应用:迭代器如何解决真问题?

1 实时数据流处理(传感器数据)

import random
import time
def sensor_data_stream():
    """模拟无限传感器读数流"""
    while True:
        yield {'temperature': random.uniform(20, 30),
               'humidity': random.uniform(40, 60)}
# 只取前5个有效数据
stream = sensor_data_stream()
for i, data in enumerate(stream):
    if data['temperature'] > 25:
        print(f"Alert: High temp {data['temperature']:.1f}°C")
    if i >= 100:   # 处理100条后停止
        break

价值:不需要存储所有传感器数据,边产生边处理,内存恒定。

2 数据库查询分页(SQLAlchemy示例)

def paginate_query(model, page_size=50):
    page = 1
    while True:
        results = model.query.paginate(page, page_size, error_out=False).items
        if not results:
            break
        yield from results   # 生成器委托
        page += 1
# 遍历所有用户表记录(可能百万级)
for user in paginate_query(User):
    print(user.email)

注意yield from 可将子生成器元素依次产出,简化迭代器嵌套。

性能对比与最佳实践

1 速度测试:迭代器 vs 列表推导式

import time
# 方法1:列表推导式(立即生成所有元素)
start = time.time()
squares = [x**2 for x in range(1000000)]
print(f"列表推导式: {time.time()-start:.3f}秒")
# 方法2:生成器推导式(惰性)
start = time.time()
gen = (x**2 for x in range(1000000))
list(gen)   # 强制求值
print(f"生成器: {time.time()-start:.3f}秒")

结果说明:两者速度相近,但列表占用内存约 8MB(100万个整数),生成器仅约 200 字节。

2 选择指南

场景 推荐方式 原因
小数据集(<1万) 列表/元组 代码可读性高
中等数据(1万-100万) 列表推导式 速度略优
大数据集(>100万) 迭代器/生成器 内存友好
无限序列(如实时数据) 生成器 只在需要时产出
需要多次遍历 转换为列表 迭代器只能遍历一次

Q1:如何判断一个对象是否可迭代?

from collections.abc import Iterable
print(isinstance([1,2], Iterable))  # True
print(isinstance(123, Iterable))    # False

Q2:迭代器能遍历多次吗?
A:不能,迭代器是一次性消耗品,用完即止,如需多次遍历,用 list(iterator) 转为列表,或用 itertools.tee() 复制。

Q3:for 循环和 while 手动调用 next() 哪个更好?
A:通常用 for,它自动处理边界和异常,只有在需要手动控制步长或条件时(如跳过元素),才用 while+next()

Q4:生成器推导式与列表推导式有什么区别?
A:列表推导式用 ,生成器推导式用 ,前者立刻生成完整列表,后者返回生成器对象,只在迭代时计算。

迭代器是Python函数式编程和高效数据处理的基石,从基础文件遍历到自定义无限序列生成器,掌握它意味着你能用最少的资源处理最多数据,对于任何涉及大数据、实时流或内存敏感的应用,迭代器都是必杀器,建议读者亲手实现一个自定义迭代器(如素数生成器),并对比与列表存储的性能差异,这将极大加深理解。

(全文完)


综合自Python官方文档、Real Python、GeeksforGeeks、Stack Overflow等权威来源,结合实战场景重组创作。*

抱歉,评论功能暂时关闭!