Python中Iterable、Iterator与生成器的详解与比较

Python 中的 Iterable、Iterator 与生成器

  • Iterable(可迭代对象)
  • Iterator(迭代器)
  • 生成器(Generator)
  • Iterable、Iterator 与生成器的关系
  • 实际应用
  • 生成器的高级用法(send())
  • 总结
  • 在 Python 中,Iterable、Iterator 和 生成器 是三个密切相关的概念,它们都与迭代操作有关,但各自扮演不同的角色。本文将深入探讨它们的定义、区别以及实际应用。

    Iterable(可迭代对象)

    定义
    Iterable 是指任何可以被迭代的对象,即能够通过 for 循环或其他迭代工具(如 map、filter 等)进行遍历的对象。

    特点
    实现了 iter() 方法,该方法返回一个 Iterator 对象。
    常见的 Iterable 类型包括:列表(list)、元组(tuple)、字符串(str)、字典(dict)、集合(set)等。
    示例

    my_list = [1, 2, 3]
    for item in my_list:
        print(item)
    

    这里 my_list 是一个 Iterable,因为它实现了 iter() 方法。

    Iterator(迭代器)

    定义
    Iterator 是实际执行迭代操作的对象,它负责在每次迭代时返回下一个值。

    特点
    实现了 iter() 方法(返回自身)和 next() 方法(返回下一个值,如果没有更多值则抛出 StopIteration 异常)。
    Iterator 是惰性的,只有在需要时才会生成值。
    示例

    my_list = [1, 2, 3]
    my_iterator = iter(my_list)  # 获取迭代器 
    print(next(my_iterator))  # 输出 1 
    print(next(my_iterator))  # 输出 2 
    print(next(my_iterator))  # 输出 3 
    print(next(my_iterator))  # 抛出 StopIteration 异常
    

    这里 my_iterator 是一个 Iterator,它通过 next() 方法逐个返回列表中的值。

    生成器(Generator)

    定义
    生成器是一种特殊的 Iterator,它通过函数和 yield 关键字定义,能够按需生成值。

    特点
    使用 yield 关键字实现,代码更简洁。
    生成器是惰性的,只有在需要时才会生成值。
    生成器函数返回一个生成器对象,该对象可以像 Iterator 一样使用。
    示例

    def my_generator():
        yield 1 
        yield 2 
        yield 3 
     
    gen = my_generator()
    for num in gen:
        print(num)  # 输出 1, 2, 3 
    

    Iterable、Iterator 与生成器的关系

    关系总结

  • Iterable 是数据的容器,而 Iterator 是遍历数据的工具。
  • Iterable 可以通过 iter() 函数转换为 Iterator。
  • 生成器是一种特殊的 Iterator,它通过 yield 关键字实现。
  • 区别

    特性 lterable Iterator 生成器
    定义方式 实现 iter() 方法。 实现 iter() 和 next() 方法。 使用 yield 关键字定义。
    实现复杂度 简单,只需实现 iter() 方法。 需要手动实现 next() 方法。 代码简洁,自动实现迭代逻辑。
    内存占用 可能占用较多内存(存储所有数据)。 惰性求值,节省内存。 惰性求值,内存占用更少。
    适用场景 数据容器(如列表、字典等)。 复杂逻辑或显式控制迭代过程。 简单逻辑或需要快速生成数据的场景。

    实际应用

    自定义 Iterable 和 Iterator

    class MyRange:
        def __init__(self, start, end):
            self.start  = start 
            self.end  = end 
     
        def __iter__(self):
            return MyRangeIterator(self.start,  self.end) 
     
    class MyRangeIterator:
        def __init__(self, start, end):
            self.current  = start 
            self.end  = end 
     
        def __iter__(self):
            return self 
     
        def __next__(self):
            if self.current  < self.end: 
                value = self.current  
                self.current  += 1 
                return value 
            else:
                raise StopIteration 
     
    for num in MyRange(1, 4):
        print(num)  # 输出 1, 2, 3 
    

    生成器的高级用法(send())

    基本功能

  • send() 是生成器对象的一个方法,用于向生成器发送一个值,并继续执行生成器函数。
  • 发送的值会成为当前 yield 表达式的结果。
  • send() 方法会返回生成器生成的下一个值。
  • 使用场景
    当生成器需要与外部代码交互时,send() 可以用于动态地向生成器传递数据。常用于协程(Coroutine)或状态机的实现。

    基本用法

    def my_generator():
        print("Start")
        x = yield 1  # 第一次 yield 
        print(f"Received: {x}")
        y = yield 2  # 第二次 yield 
        print(f"Received: {y}")
     
    # 创建生成器对象 
    gen = my_generator()
     
    # 启动生成器 
    print(next(gen))  # 输出 Start, 返回 1 
     
    # 发送值给生成器 
    print(gen.send(10))   # 输出 Received: 10, 返回 2 
     
    # 再次发送值 
    try:
        gen.send(20)   # 输出 Received: 20 
    except StopIteration:
        print("Generator finished")
    

    协程示例

    def coroutine():
        total = 0 
        while True:
            value = yield total 
            total += value 
     
    # 创建协程 
    co = coroutine()
     
    # 启动协程 
    next(co)
     
    # 发送值并获取结果 
    print(co.send(10))   # 输出 10 
    print(co.send(20))   # 输出 30 
    print(co.send(5))    # 输出 35 
    

    总结

  • Iterable 是数据容器,Iterator 是遍历工具,生成器 是特殊的 Iterator。
  • 生成器通过 yield 关键字实现,代码简洁且内存效率高。
  • 理解这三者的区别和联系,有助于更好掌握 Python 的迭代机制,并在需要时自定义迭代行为。
    希望这篇博客对你有所帮助!如果还有疑问,欢迎留言讨论。

    作者:CavenWang

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python中Iterable、Iterator与生成器的详解与比较

    发表回复