Python案例中的迭代器怎么实现?

wen python案例 8

本文目录导读:

Python案例中的迭代器怎么实现?

  1. 使用类实现迭代器
  2. 使用生成器函数实现迭代器
  3. 实战案例:自定义文件行读取器
  4. 组合迭代器:实现可迭代对象 + 迭代器
  5. 迭代器的常用技巧

在Python中,实现迭代器主要有两种方式:使用实现(通过 __iter____next__ 方法)或使用生成器函数(通过 yield 关键字),下面通过具体案例来说明。

使用类实现迭代器

这种方式需要定义一个类,实现两个特殊方法:

  • __iter__():返回迭代器对象本身
  • __next__():返回下一个值,如果没有更多元素则抛出 StopIteration 异常

案例1:实现一个简单的数字迭代器(生成1到n的平方)

class SquareIterator:
    """生成1到n的平方数的迭代器"""
    def __init__(self, n):
        self.n = n
        self.current = 1
    def __iter__(self):
        return self
    def __next__(self):
        if self.current <= self.n:
            result = self.current ** 2
            self.current += 1
            return result
        else:
            raise StopIteration
# 使用示例
squares = SquareIterator(5)
for num in squares:
    print(num)
# 输出: 1, 4, 9, 16, 25

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

class FibonacciIterator:
    """生成斐波那契数列的迭代器,生成指定数量的项"""
    def __init__(self, count):
        self.count = count
        self.a, self.b = 0, 1
        self.index = 0
    def __iter__(self):
        return self
    def __next__(self):
        if self.index >= self.count:
            raise StopIteration
        if self.index == 0:
            result = self.a
        elif self.index == 1:
            result = self.b
        else:
            result = self.a + self.b
            self.a, self.b = self.b, result
        self.index += 1
        return result
# 使用示例
fib = FibonacciIterator(10)
print(list(fib))  # 输出: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

使用生成器函数实现迭代器

生成器是Python中更简洁的实现方式,使用 yield 关键字而非 return

案例3:使用生成器实现平方数迭代

def square_generator(n):
    """生成1到n的平方数的生成器函数"""
    for i in range(1, n + 1):
        yield i ** 2
# 使用示例
for num in square_generator(5):
    print(num)
# 输出: 1, 4, 9, 16, 25

案例4:无限斐波那契数列生成器

def fibonacci_generator():
    """生成无限的斐波那契数列"""
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b
# 使用示例 - 只取前10个
fib = fibonacci_generator()
for i in range(10):
    print(next(fib))
# 输出: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

实战案例:自定义文件行读取器

这个案例展示如何创建一个可以逐行读取文件的迭代器,支持自定义处理逻辑。

class FileLineIterator:
    """自定义文件行读取迭代器,支持前缀添加"""
    def __init__(self, filepath, prefix=""):
        self.filepath = filepath
        self.prefix = prefix
        self.file = None
    def __iter__(self):
        self.file = open(self.filepath, 'r', encoding='utf-8')
        return self
    def __next__(self):
        if self.file is None:
            raise StopIteration
        line = self.file.readline()
        if not line:
            self.file.close()
            self.file = None
            raise StopIteration
        return f"{self.prefix}: {line.strip()}"
# 使用示例(假设有一个 test.txt 文件)
# iterator = FileLineIterator('test.txt', prefix='行')
# for line in iterator:
#     print(line)

组合迭代器:实现可迭代对象 + 迭代器

有时候需要实现一个可迭代对象(包含迭代器)而不是直接实现迭代器。

class Range:
    """模拟内建的 range 函数"""
    def __init__(self, start, stop=None, step=1):
        if stop is None:
            self.start = 0
            self.stop = start
        else:
            self.start = start
            self.stop = stop
        self.step = step
    def __iter__(self):
        return RangeIterator(self.start, self.stop, self.step)
class RangeIterator:
    """Range 的迭代器"""
    def __init__(self, start, stop, step):
        self.current = start
        self.stop = stop
        self.step = step
    def __iter__(self):
        return self
    def __next__(self):
        if self.step > 0 and self.current >= self.stop:
            raise StopIteration
        if self.step < 0 and self.current <= self.stop:
            raise StopIteration
        result = self.current
        self.current += self.step
        return result
# 使用示例
my_range = Range(1, 6)
print(list(my_range))  # 输出: [1, 2, 3, 4, 5]

迭代器的常用技巧

技巧1:使用 __getitem__ 实现简单迭代

class SimpleIterable:
    """通过 __getitem__ 实现迭代"""
    def __init__(self, data):
        self.data = data
    def __getitem__(self, index):
        return self.data[index]
# 自动支持迭代
obj = SimpleIterable([1, 2, 3, 4, 5])
for item in obj:
    print(item)  # 输出: 1, 2, 3, 4, 5

技巧2:使用 itertools 模块处理迭代器

from itertools import islice, cycle, takewhile
# 组合使用生成器和itertools
def infinite_counter(start=0):
    while True:
        yield start
        start += 1
# 只取前5个
counter = infinite_counter()
first_five = list(islice(counter, 5))
print(first_five)  # 输出: [0, 1, 2, 3, 4]
# 循环使用
cycle_data = cycle(['A', 'B', 'C'])
first_six = list(islice(cycle_data, 6))
print(first_six)  # 输出: ['A', 'B', 'C', 'A', 'B', 'C']

实现迭代器的关键点:

  1. 类实现方式:必须实现 __iter__()__next__() 方法,并在适当时候抛出 StopIteration
  2. 生成器方式:使用 yield 关键字,更简洁,自动处理状态和异常
  3. 迭代器特点
    • 一次性使用(遍历完后不能再使用)
    • 惰性计算(需要时才生成值)
    • 节省内存(不一次加载所有数据)

建议:对于简单场景,优先使用生成器;对于需要复杂状态管理的场景,使用类实现迭代器。

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