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 的迭代机制,并在需要时自定义迭代行为。
希望这篇博客对你有所帮助!如果还有疑问,欢迎留言讨论。

你可能感兴趣的:(python,python,开发语言)