Python进阶:可迭代对象、迭代器与生成器

张开发
2026/4/18 5:51:27 15 分钟阅读

分享文章

Python进阶:可迭代对象、迭代器与生成器
一、可迭代对象在 Python 中我们把能够使用for循环进行遍历的对象统称为可迭代对象。它是迭代机制的基础载体是我们最常接触的数据类型。1. 可迭代对象的常见类型Python 中内置的容器类型绝大多数都是可迭代对象主要包括列表 (list)、元组 (tuple)、字符串 (str)、字典 (dict)、集合 (set)、生成器 (generator) 等。2. 可迭代对象的核心特征可迭代对象的本质是实现了__iter__()方法的对象。当我们对一个可迭代对象使用iter()函数时Python 会自动调用其内部的__iter__()方法将其转换为迭代器这是可迭代对象与迭代器之间转换的桥梁。简单来说可迭代对象只具备 可被遍历 的能力但不具备直接逐个获取元素的能力必须转换为迭代器才能实现。二、迭代器迭代器是Python迭代机制的执行核心它是由可迭代对象转换而来的特殊对象具备惰性取值、一次性遍历的核心特性。1. 迭代器的创建我们可以通过Python内置函数iter()将可迭代对象转换为迭代器这是迭代器最常用的创建方式list_1 [1, 2, 3, 4, 5, 6] # 调用iter()函数将列表转换为迭代器 iterator iter(list_1)2. 迭代器的iter()和next()方法迭代器依赖两个核心方法实现迭代功能iter()和next()。iter()将可迭代对象转换为迭代器next()逐个获取迭代器中的元素每调用一次就返回下一个元素。代码示例list_1 [1, 2, 3, 4, 5, 6] # 将可迭代对象转换为迭代器 iterator iter(list_1) # 使用next()逐个取值 print(next(iterator)) # 输出1 print(next(iterator)) # 输出2 print(next(iterator)) # 输出33. 迭代器的一次性遍历迭代器最大的特点是只能遍历一次元素会被消耗。当我们使用next()或for循环遍历完迭代器的所有元素后迭代器就会清空无法再次遍历。list_1 [1, 2, 3, 4, 5, 6] # 将可迭代对象转换为迭代器 iterator iter(list_1) # 使用next()逐个取值 print(next(iterator)) # 输出1 print(next(iterator)) # 输出2 print(next(iterator)) # 输出3 print(**20) # for循环遍历迭代器只会输出未被next()读取的剩余元素 for item in iterator: print(item) # 输出4、5、6程序运行结果原因迭代器是惰性序列它不会在内存中存储所有元素而是在调用next()时才计算并返回下一个元素元素被取出后就会被释放因此无法重复遍历。4. for循环遍历迭代器的原理我们使用for循环遍历迭代器时Python底层自动完成了三步操作调用iter()函数获取迭代器对象循环调用next()函数逐个获取元素捕获StopIteration异常自动结束循环。这也是for循环能遍历所有可迭代对象的底层逻辑。5. 可迭代和迭代器的判断Python提供了collections.abc模块判断对象类型from collections.abc import Iterator, Iterable # 判断列表是否为迭代器 print(isinstance([], Iterator)) # 输出False # 判断列表是否为可迭代对象 print(isinstance([], Iterable)) # 输出True三、生成器特殊的迭代器生成器是 Python 中自带迭代器功能的特殊对象是迭代器的子集也是 Python 实现惰性计算的最佳工具。1. 生成器的定义生成器的核心是yield关键字在函数中使用yield替代return返回数据这个函数就不再是普通函数而是生成器函数调用后会返回生成器对象。# 定义生成器函数 def gen_func(): yield 1 yield 2 yield 3 # 创建生成器对象 gen gen_func()2. 生成器的核心特性生成器对象本质就是迭代器对象它完全具备迭代器的所有特性支持next()取值、支持for循环遍历、一次性消耗、惰性计算。# 定义生成器函数 def gen_func(): yield 1 yield 2 yield 3 # 创建生成器对象 gen gen_func() # 生成器可以直接使用next() print(next(gen)) # 输出1 # 生成器可以用for循环遍历 for item in gen: print(item) # 输出2 3普通迭代器需要基于可迭代对象创建而生成器可以自定义迭代逻辑不需要提前创建数据序列。4. 创建生成器1生成器函数用 yield 关键字普通函数里把return换成yield这个函数就变成生成器函数调用函数不会执行代码而是返回一个生成器对象。可以多次yield暂停保存状态按需产出数据适合逻辑复杂、多步骤的场景。2生成器表达式与列表推导式语法几乎一致唯一区别是将列表推导式的[]方括号改为()圆括号。一行代码就能实现适合逻辑简单、无需复杂步骤的场景。5. 生成器表达式与列表推导式的对比生成器表达式与列表推导式外观相似但在内存占用、取值特性等核心维度差异显著具体区别如下1语法列表推导式用[]方括号包裹例如[i for i in range(10)]生成器表达式用()圆括号包裹例如(i for i in range(10))。2内存列表推导式一次性把所有元素全部创建并存入内存处理大了数据时会占用极高的内存甚至导致程序卡顿、内存溢出生成器表达式采用“惰性加载”机制只保存生成数据不需要提前创建任何元素用一个算一个全程几乎不占用内存。3取值列表推导式生成的列表是可迭代对象支持重复取值、索引、切片操作可多次用for循环遍历list_1 [i for i in range( 5 )] print( list_1[2] ) # 支持索引输出2生成器表达式生成的生成器是迭代器只能一次性消耗遍历完后元素全部清空不支持索引、切片操作再次遍历无任何输出。gen_temp (i for i in range(5)) # print(gen_comp[2]) # 直接报错不支持索引 for num in gen_temp: # 第一次遍历消耗全部元素 输出 0 1 2 3 4 print(num) for num in gen_temp: # 第二次遍历无任何输出 print(num)4类型列表推导式 → 生成list类型只是可迭代对象不是迭代器生成器表达式 → 生成generator类型本身就是迭代器具备迭代器的所有特性。from collections.abc import Iterator list_temp [i for i in range(5)] gen_temp (i for i in range(5)) print(isinstance(list_temp, Iterator)) # 输出 False print(isinstance(gen_temp, Iterator)) # 输出 True四、为什么需要迭代器迭代器是 Python 的核心设计之一它的存在解决了两大关键问题1. 节省内存高效处理海量数据列表、元组等可迭代对象会一次性将所有元素加载到内存中当处理百万、千万级海量数据时会极大占用内存资源。而迭代器是惰性计算只有在需要取值时才生成元素全程只占用一个元素的内存空间极大提升了程序的内存利用率。2. 统一遍历规则简化代码逻辑Python 中有列表、字符串、字典等多种可迭代容器它们的内部结构完全不同但迭代器为所有容器提供了统一的遍历接口。我们无需关心容器的底层结构只需要使用iter()和next()就能实现统一遍历大幅降低了编程的复杂度。五、总结可迭代对象可通过 for 循环遍历核心是实现__iter__() 方法常见类型有列表、元组等需通过 iter () 函数转换为迭代器才能逐个取值。迭代器由可迭代对象通过 iter () 创建依赖 iter () 和 next () 方法具备惰性取值、一次性遍历特性for 循环遍历其底层是自动获取迭代器、调用 next () 并捕获异常。可通过 isinstance () 结合 Iterator、Iterable 判断类型。生成器特殊的迭代器核心是 yield 关键字有生成器函数多 yield、适合复杂逻辑和生成器表达式() 包裹、适合简单逻辑两种写法与列表推导式在语法、内存、取值、类型上差异显著。迭代器的作用解决海量数据内存占用问题统一各类可迭代容器的遍历规则简化编程逻辑。

更多文章