迭代器基础

Python 中的迭代器本质是实现 __iter__()__next__() 方法的对象。迭代器的声明和创建可以通过以下方式实现:

class MyIterator:
    def __init__(self, data):
        self.data = data
        self.index = 0
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.index >= len(self.data):
            raise StopIteration
        value = self.data[self.index]
        self.index += 1
        return value

# 使用自定义迭代器
my_iter = MyIterator([10, 20, 30])
for item in my_iter:
    print(item)  # 输出: 10, 20, 30
可迭代对象与迭代器

使用内置函数可以方便地进行迭代器的创建和遍历操作:

# 列表是可迭代对象,但不是迭代器
my_list = [1, 2, 3, 4, 5]
my_iter = iter(my_list)  # 获取迭代器

print(next(my_iter))  # 1
print(next(my_iter))  # 2

# 使用 for 循环遍历
for item in iter(my_list):
    print(item)
常用迭代器处理函数

Python 内置了丰富的迭代器处理函数:

# 枚举迭代器
fruits = ["apple", "banana", "cherry"]
for index, fruit in enumerate(fruits):
    print(f"{index}: {fruit}")

# zip 并行迭代
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
for name, age in zip(names, ages):
    print(f"{name} is {age} years old")

# map 映射迭代
numbers = [1, 2, 3, 4, 5]
squared = map(lambda x: x ** 2, numbers)
print(list(squared))  # [1, 4, 9, 16, 25]

# filter 过滤迭代
evens = filter(lambda x: x % 2 == 0, numbers)
print(list(evens))  # [2, 4]
生成器函数

生成器使用 yield 关键字,可以暂停和恢复执行,节省内存:

def countdown(n):
    while n > 0:
        yield n
        n -= 1

# 使用生成器
for num in countdown(5):
    print(num)  # 输出: 5, 4, 3, 2, 1

# 生成器表达式
squares = (x ** 2 for x in range(10))
print(sum(squares))  # 285
生成器表达式

处理大量数据时可以使用生成器表达式替代列表推导式:

# 列表推导式(占用内存)
list_comp = [x ** 2 for x in range(1000000)]

# 生成器表达式(惰性求值)
gen_exp = (x ** 2 for x in range(1000000))

# 按需获取
print(next(gen_exp))  # 0
print(next(gen_exp))  # 1

# 遍历使用
for val in (x for x in range(10) if x % 2 == 0):
    print(val)  # 0, 2, 4, 6, 8
文件迭代示例

逐行读取文件是一个常见操作,使用生成器可以高效处理大文件:

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('data.txt'):
    if 'error' in line:
        print(line)
安全迭代处理

为防止迭代器耗尽,推荐在需要多次遍历时使用列表或重新创建迭代器:

# 迭代器只能遍历一次
data = iter([1, 2, 3])
print(list(data))  # [1, 2, 3]
print(list(data))  # [] 已耗尽

# 解决方案:转换为列表或重新创建
original = [1, 2, 3]
first_pass = list(original)
second_pass = list(original)

# 使用 itertools.tee 复制迭代器
from itertools import tee
it1, it2 = tee(iter([1, 2, 3]))
print(list(it1))  # [1, 2, 3]
print(list(it2))  # [1, 2, 3]
自定义生成器函数

实现自定义的生成器可以加深对惰性求值的理解:

def fibonacci_generator(n):
    """生成斐波那契数列的前 n 项"""
    a, b = 0, 1
    count = 0
    while count < n:
        yield a
        a, b = b, a + b
        count += 1

# 使用自定义生成器
for num in fibonacci_generator(10):
    print(num, end=' ')  # 0 1 1 2 3 5 8 13 21 34

# 转换为列表
print(list(fibonacci_generator(5)))  # [0, 1, 1, 2, 3]
性能注意事项

迭代器与生成器在 Python 中需要特别注意性能和内存问题:

  • 避免在需要随机访问时使用迭代器

  • 优先使用生成器表达式处理大数据流

  • 考虑使用 itertools 模块提供的内存高效工具

以上代码示例涵盖了 Python3 迭代器与生成器的主要概念和操作,从基础用法到高级技巧,为开发者提供了全面的参考。

更多推荐