【Python】Python之什么是生成器?什么是迭代器?

发布于:2025-06-24 ⋅ 阅读:(18) ⋅ 点赞:(0)

专栏导读

  • 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手

  • 🏳️‍🌈 博客主页:请点击——> 一晌小贪欢的博客主页求关注

  • 👍 该系列文章专栏:请点击——>Python办公自动化专栏求订阅

  • 🕷 此外还有爬虫专栏:请点击——>Python爬虫基础专栏求订阅

  • 📕 此外还有python基础专栏:请点击——>Python基础学习专栏求订阅

  • 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏

  • ❤️ 欢迎各位佬关注! ❤️

前言

在Python编程中,迭代器(Iterator)和生成器(Generator)是两个非常重要且强大的概念。它们不仅能让我们的代码更加优雅和高效,还能帮助我们处理大量数据时节省内存。本文将深入探讨这两个概念,并通过丰富的示例来帮助大家理解和掌握它们。

什么是迭代器(Iterator)?

迭代器的定义

迭代器是一个可以记住遍历位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

迭代器协议

在Python中,迭代器需要实现两个方法:

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

可迭代对象 vs 迭代器

# 可迭代对象(Iterable)
my_list = [1, 2, 3, 4, 5]
my_string = "hello"
my_dict = {'a': 1, 'b': 2}

# 检查是否为可迭代对象
from collections.abc import Iterable
print(isinstance(my_list, Iterable))  # True
print(isinstance(my_string, Iterable))  # True
print(isinstance(my_dict, Iterable))  # True

# 获取迭代器
list_iterator = iter(my_list)
print(type(list_iterator))  # <class 'list_iterator'>

# 使用迭代器
print(next(list_iterator))  # 1
print(next(list_iterator))  # 2
print(next(list_iterator))  # 3

自定义迭代器

class NumberIterator:
    def __init__(self, start, end):
        self.start = start
        self.end = end
        self.current = start
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.current < self.end:
            result = self.current
            self.current += 1
            return result
        else:
            raise StopIteration

# 使用自定义迭代器
numbers = NumberIterator(1, 5)
for num in numbers:
    print(num)  # 输出: 1, 2, 3, 4

迭代器的优势

1. **内存效率**:迭代器是惰性求值的,只在需要时才计算下一个值
2. **节省空间**:不需要将所有元素同时存储在内存中
3. **适合处理大数据集**:可以处理无限序列或非常大的数据集

什么是生成器(Generator)?

生成器的定义

生成器是一种特殊的迭代器,它使用`yield`关键字来产生值。生成器函数在调用时不会立即执行,而是返回一个生成器对象。

生成器函数

def simple_generator():
    yield 1
    yield 2
    yield 3

# 创建生成器对象
gen = simple_generator()
print(type(gen))  # <class 'generator'>

# 使用生成器
print(next(gen))  # 1
print(next(gen))  # 2
print(next(gen))  # 3
# print(next(gen))  # 会抛出 StopIteration 异常

生成器表达式

# 列表推导式
squares_list = [x**2 for x in range(10)]
print(type(squares_list))  # <class 'list'>

# 生成器表达式
squares_gen = (x**2 for x in range(10))
print(type(squares_gen))  # <class 'generator'>

# 比较内存使用
import sys
print(f"列表大小: {sys.getsizeof(squares_list)} bytes")
print(f"生成器大小: {sys.getsizeof(squares_gen)} bytes")

复杂的生成器示例

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

# 使用斐波那契生成器
fib_gen = fibonacci_generator(10)
for num in fib_gen:
    print(num, end=" ")  # 输出: 0 1 1 2 3 5 8 13 21 34
print()

生成器的状态保持

def counter_generator():
    count = 0
    while True:
        value = yield count
        if value is not None:
            count = value
        else:
            count += 1

# 使用带状态的生成器
counter = counter_generator()
print(next(counter))  # 0
print(next(counter))  # 1
print(counter.send(10))  # 10
print(next(counter))  # 11

迭代器 vs 生成器对比

特性 迭代器 生成器
定义方式 实现__iter____next__方法 使用yield关键字或生成器表达式
代码复杂度 相对复杂 简洁优雅
内存使用 惰性求值 惰性求值
状态管理 手动管理 自动管理
是否为迭代器 是(特殊的迭代器)

实际应用场景

1. 读取大文件

def read_large_file(file_path):
    """逐行读取大文件,节省内存"""
    with open(file_path, 'r', encoding='utf-8') as file:
        for line in file:
            yield line.strip()

# 使用示例
# for line in read_large_file('large_file.txt'):
#     process_line(line)

2. 数据流处理

def data_processor(data_source):
    """处理数据流"""
    for item in data_source:
        # 进行数据清洗和转换
        processed_item = item.upper().strip()
        if processed_item:  # 过滤空值
            yield processed_item

# 链式处理
raw_data = ['  hello  ', '  world  ', '', '  python  ']
processed_data = data_processor(raw_data)
for item in processed_data:
    print(f"处理后: {item}")

3. 无限序列

def infinite_sequence():
    """生成无限序列"""
    num = 0
    while True:
        yield num
        num += 1

# 使用无限序列(注意要有退出条件)
inf_gen = infinite_sequence()
for i, num in enumerate(inf_gen):
    if i >= 10:  # 只取前10个
        break
    print(num, end=" ")  # 输出: 0 1 2 3 4 5 6 7 8 9
print()

高级特性

1. 生成器的方法

def advanced_generator():
    try:
        value = yield "开始"
        while True:
            if value == "stop":
                return "生成器结束"
            value = yield f"接收到: {value}"
    except GeneratorExit:
        print("生成器被关闭")
    finally:
        print("清理资源")

# 使用生成器方法
gen = advanced_generator()
print(next(gen))  # 开始
print(gen.send("hello"))  # 接收到: hello
print(gen.send("world"))  # 接收到: world
try:
    print(gen.send("stop"))  # 抛出 StopIteration,值为 "生成器结束"
except StopIteration as e:
    print(f"返回值: {e.value}")

2. 异常处理

def error_handling_generator():
    try:
        yield 1
        yield 2
        yield 3
    except ValueError as e:
        yield f"捕获到错误: {e}"
        yield "继续执行"

gen = error_handling_generator()
print(next(gen))  # 1
print(gen.throw(ValueError, "测试错误"))  # 捕获到错误: 测试错误
print(next(gen))  # 继续执行

性能比较

import time
import sys

def performance_comparison():
    # 列表方式
    start_time = time.time()
    squares_list = [x**2 for x in range(1000000)]
    list_time = time.time() - start_time
    list_memory = sys.getsizeof(squares_list)
    
    # 生成器方式
    start_time = time.time()
    squares_gen = (x**2 for x in range(1000000))
    gen_time = time.time() - start_time
    gen_memory = sys.getsizeof(squares_gen)
    
    print(f"列表创建时间: {list_time:.6f}秒")
    print(f"生成器创建时间: {gen_time:.6f}秒")
    print(f"列表内存使用: {list_memory:,} bytes")
    print(f"生成器内存使用: {gen_memory:,} bytes")
    print(f"内存节省比例: {(list_memory - gen_memory) / list_memory * 100:.2f}%")

performance_comparison()

最佳实践

1. 何时使用迭代器

  • 需要自定义复杂的迭代逻辑
  • 需要实现特殊的迭代行为
  • 构建可重用的迭代器类

2. 何时使用生成器

  • 处理大量数据时节省内存
  • 创建数据流水线
  • 实现惰性求值
  • 生成无限序列

3. 注意事项

# 生成器只能迭代一次
gen = (x for x in range(3))
print(list(gen))  # [0, 1, 2]
print(list(gen))  # [] 空列表,生成器已耗尽

# 如果需要多次迭代,重新创建生成器
def create_generator():
    return (x for x in range(3))

gen1 = create_generator()
gen2 = create_generator()
print(list(gen1))  # [0, 1, 2]
print(list(gen2))  # [0, 1, 2]

总结

迭代器和生成器是Python中强大的工具,它们提供了优雅且内存高效的方式来处理数据序列。主要要点包括:

  • 1. **迭代器**是实现了迭代器协议的对象,可以逐个访问元素
  • 2. **生成器**是特殊的迭代器,使用`yield`关键字,代码更简洁
  • 3. 两者都支持**惰性求值**,节省内存空间
  • 4. 适用于处理**大数据集**和**无限序列**
  • 5. 生成器提供了`send()`、`throw()`、`close()`等高级方法

掌握迭代器和生成器的使用,将让你的Python代码更加高效和优雅。在处理大量数据或需要节省内存的场景中,它们是不可或缺的工具。


结尾

  • 希望对初学者有帮助;致力于办公自动化的小小程序员一枚

  • 希望能得到大家的【❤️一个免费关注❤️】感谢!

  • 求个 🤞 关注 🤞 +❤️ 喜欢 ❤️ +👍 收藏 👍

  • 此外还有办公自动化专栏,欢迎大家订阅:Python办公自动化专栏

  • 此外还有爬虫专栏,欢迎大家订阅:Python爬虫基础专栏

  • 此外还有Python基础专栏,欢迎大家订阅:Python基础学习专栏


网站公告

今日签到

点亮在社区的每一天
去签到