Python入门——yield生成器和iter迭代器

yield生成器

yield 的作用

  • 生成器函数 :yield 将一个普通的函数变成一个生成器函数 。生成器函数与普通函数的区别在于,普通函数使用 return 一次性返回结果并终止,而生成器函数使用 yield 返回一个值后,会记住函数的执行状态,暂停执行,待下一次被调用时继续执行。
  • 惰性计算:生成器不会一次性生成所有结果,而是按需生成。这种方式称为"惰性计算"(lazy evaluation),非常节省内存,尤其适用于处理大数据或流式数据的场景。

yield 的工作原理

当生成器函数包含 yield 时,每次调用生成器对象的 next() 方法时,生成器会执行到 yield 语句,返回当前值并暂停。下一次调用 next() 时,生成器从上次暂停的位置继续执行,直到遇到下一个 yield 或函数结束。

基本用法

当一个函数包含 yield 关键字时,该函数不再是普通的函数,而是一个生成器函数。调用生成器函数时,它不会立即执行,而是返回一个生成器对象,允许你通过迭代的方式来逐步获取值。

示例:

python 复制代码
def simple_generator():
    print("First value:")
    yield 1  # 第一次暂停并返回值1
    print("Second value:")
    yield 2  # 第二次暂停并返回值2
    print("Third value:")
    yield 3  # 第三次暂停并返回值3

# 调用生成器函数,返回一个生成器对象
gen = simple_generator()

# 通过 next() 获取生成器中的值
print(next(gen))  # 输出: First value: 1
print(next(gen))  # 输出: Second value: 2
print(next(gen))  # 输出: Third value: 3

yield 与 return 的区别:

  • return :函数遇到 return 后,直接返回值,并终止函数的执行。
  • yield :函数遇到 yield 后,会返回一个值给调用者,同时函数的状态会被"冻结" ,即函数在 yield 处暂停,等待下一次调用时继续执行,而不是从头开始。

使用场景:

  1. 惰性求值:当处理大量数据时,生成器可以惰性计算,不必一次性将所有数据加载到内存中。
  2. 流式处理:当数据源的数据量过大,或数据是实时产生的(如读取文件、网络流等),生成器可用来逐步产生数据。
  3. 协程 :在 Python 中,yield 也被用于协程中来实现异步操作。

示例:生成一个范围内的数字

python 复制代码
def number_generator(n):
    for i in range(n):
        yield i

gen = number_generator(5)

for number in gen:
    print(number)

优点

  1. 节省内存 :相比一次性加载所有数据,生成器通过 yield 逐步生成数据,避免了占用大量内存。
  2. 效率高:适合处理大量数据或流式数据的场景,且生成器函数编写简单明了。
  3. 易于实现复杂的迭代逻辑:生成器允许在多次调用之间保存函数的执行状态,使其能够简洁地实现复杂的迭代逻辑。

总结

  • yield 关键字让你可以创建生成器函数,用于逐步生成值,而不是一次性生成所有值。
  • 生成器可以用于高效处理大量数据或实现惰性求值。

iter迭代器

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

迭代器的核心概念

properties 复制代码
迭代器协议: 任何实现了 __iter__()和 __next__()方法的对象都是迭代器。

__iter__(): 返回迭代器对象本身。
__next__(): 返回容器的下一个元素,直到没有元素时抛出 `StopIteration` 异常。

示例:

python 复制代码
# 自定义一个简单的迭代器
class MyIterator:
    def __init__(self, data):
        self.data = data
        self.index = 0  # 用来记录当前访问的位置

    def __iter__(self):
        return self  # 迭代器的 __iter__ 方法返回自身

    def __next__(self):
        if self.index < len(self.data):
            value = self.data[self.index]
            self.index += 1
            return value
        else:
            raise StopIteration  # 当没有更多元素时,抛出 StopIteration 异常

# 使用该迭代器
my_list = [1, 2, 3, 4]
my_iter = MyIterator(my_list)

for item in my_iter:
    print(item)		# 结果 1'\n' 2.. 3.. 4..
"""
解释:
这个 MyIterator 类实现了 __iter__() 和 __next__() 方法,因此它是一个迭代器。
在 for 循环中,Python 自动调用 __iter__() 方法来获取迭代器对象,并在每次循环时调用 __next__() 来获取下一个元素。
当所有元素都遍历完后,__next__() 方法抛出 StopIteration,循环就会结束。
"""

内置迭代器

Python 的许多内置数据类型都是可迭代的,比如列表、元组、字符串、字典和集合等。你可以通过 iter() 函数将这些对象转换为迭代器。

python 复制代码
my_list = [1, 2, 3, 4]
my_iter = iter(my_list)

print(next(my_iter))  # 输出: 1
print(next(my_iter))  # 输出: 2
print(next(my_iter))  # 输出: 3
print(next(my_iter))  # 输出: 4
print(next(my_iter))  # 抛出 StopIteration 异常
# Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

迭代器与可迭代对象的区别

  • 可迭代对象(Iterable) :实现了 __iter__() 方法,返回一个迭代器对象的对象。如列表、元组、字典、集合等。
  • 迭代器(Iterator) :实现了 __iter__() 和 __next__() 方法的对象。

可迭代对象可以通过 iter() 函数得到一个迭代器,迭代器可以用 next() 函数不断获取元素直到抛出 StopIteration 异常。

迭代器的应用场景

迭代器适用于遍历数据,不要求将所有数据一次性加载到内存中,特别适合处理大量数据或流数据。

文件读取示例

python 复制代码
with open('test.txt', 'r') as file:
    for line in file:  # 文件对象是一个迭代器,每次读取一行
        print(line.strip())

总结

  • 迭代器是一种可以记住访问位置的对象,遵循迭代器协议(__iter__() 和 __next__() 方法)。
  • 迭代器可以高效地处理数据流,避免将整个数据集一次性加载到内存中。
  • 许多内置对象都是可迭代的,并且可以通过 iter() 转换为迭代器。

相关推荐
weixin_307779132 小时前
C++代码实现MATLAB中的dlarray函数功能
开发语言·c++·算法·matlab
一水鉴天5 小时前
映射、哈希表与哈斯图:计算机科学的三种基线 20261003(元宝)
开发语言·人工智能
Frank_refuel5 小时前
C++11之一场名为“搬家”的 C++ 之旅
开发语言·c++
海绵宝宝转agent6 小时前
learn-claude-code第1-5章开源学习笔记分享
人工智能·笔记·python·学习
小奇不哭6 小时前
ROS2 单节点,RGB-D 深度相机局部路径提取 + B 样条平滑路径 + YOLOv8 障碍物检测 + 深度测距,用于移动机器人视觉局部循迹。
python·yolov8·ros2·cv2·路径探索循迹
小小龙学IT6 小时前
Python scikit-learn 机器学习库深度解析
python·机器学习·scikit-learn
Wang's Blog6 小时前
Java 项目实战: 外卖平台优化-Nginx配置文件结构与块层级
java·开发语言·nginx
2601_962071577 小时前
类变量和全局变量的查找路径有什么区别?
开发语言·python
卷无止境8 小时前
独立开发者的"富矿地带":哪些垂直领域值得你押注一辈子?
后端·python
\光辉岁月/8 小时前
5.java-数组
java·开发语言