Python3 可迭代对象
Python3 可迭代对象
本文中交替出现 Python 的编译模式和交互模式代码块,为便于区分,带有
>>>
的 Python 代码块为交互模式,其余 Python 代码块为编译模式。
可迭代对象是Python3 最伟大的发明,是Python3区别于其它编程语言的最显著特征。掌握好可迭代对象才是真正学好了Python3.
可迭代对象(Iterable)
定义
可迭代对象(Iterable)是指在 Python 中能够使用迭代器进行遍历的对象。它包括了各种容器对象,如列表(list)、元组(tuple)、集合(set)、字典(dict)以及字符串等。
可迭代对象的特点是可以通过 for
循环来遍历其中的元素,或者使用内置的 iter()
函数将其转换为迭代器对象。
1 | # 列表是可迭代对象 |
基本概念和操作
在 Python 中,可迭代对象(Iterable) 是一个可以被逐个取出元素的对象,常用于 for
循环、生成器表达式、函数 iter()
中。
判断是否是可迭代对象
1 | print(isinstance([1, 2, 3], Iterable)) # True(列表) |
常见可迭代对象类型
类型 | 示例 | 说明 |
---|---|---|
list |
[1, 2, 3] |
可重复遍历,可变 |
tuple |
(1, 2, 3) |
不可变 |
str |
"abc" |
每个字符是一个元素 |
dict |
{"a": 1, "b": 2} |
遍历时是键 |
set |
{1, 2, 3} |
无序不重复元素 |
range |
range(10) |
整数序列生成 |
generator |
(x for x in range(10)) |
一次性遍历,惰性计算 |
file |
open('a.txt') |
行级读取,每次一行 |
enumerate |
enumerate(lst) |
下标+元素 |
zip |
zip(a, b) |
元素打包 |
可迭代对象的高级应用
枚举(enumerate
)
1 | lst = ["a", "b", "c"] |
输出:
1 | 0 a |
同时遍历多个序列(zip
)
1 | names = ["Tom", "Jerry"] |
输出:
1 | Tom 90 |
解包可迭代对象(*
运算符)
1 | a, b, *rest = [1, 2, 3, 4, 5] |
迭代器(Iterator)
定义
迭代器(Iterator)是一种可以实现惰性计算的对象,可以被用来遍历可迭代对象中的元素。迭代器是一种特殊的对象,它实现了 __iter__()
和 __next__()
方法,这使得它可以被 next()
函数调用,并且可以逐个返回元素,直到没有元素可返回时抛出 StopIteration
异常。
迭代器的主要特点是它只在需要时才生成下一个值,这种延迟计算的方式使得迭代器在处理大数据集时非常高效,因为它不会一次性将所有数据都加载到内存中,而是按需生成和处理数据。
1 | my_list = [1, 2, 3, 4, 5] |
基本操作
将可迭代对象转为迭代器:iter()
1 | s = "hello" |
可迭代对象与迭代器对比
概念 | 是否惰性计算 | 是否可 next() |
是否可 for |
---|---|---|---|
Iterable | ❌ 否 | ❌ 不可 | ✅ 可以 |
Iterator | ✅ 是 | ✅ 可以 | ✅ 可以 |
1 | lst = [1, 2, 3] |
使用for
循环操作迭代器关系
1 | # 等价于 for i in [1, 2, 3] |
Python 3 中返回迭代器的内置函数及其应用示例
以下是在 Python 3 中返回迭代器(而非列表)的常用内置函数,它们具有惰性求值特性,适用于大数据处理:
1. map(function, iterable, ...)
返回将函数应用于每个元素的迭代器
1 | # 计算数字的平方 |
2. filter(function, iterable)
返回满足条件元素的迭代器
1 | # 筛选偶数 |
3. zip(*iterables)
返回聚合多个可迭代对象的迭代器
1 | # 合并姓名和年龄 |
4. enumerate(iterable, start=0)
返回带索引的元素迭代器
1 | # 带索引遍历 |
5. reversed(sequence)
返回反向访问的迭代器
1 | # 反向遍历列表 |
6. iter(object[, sentinel])
返回对象的迭代器
1 | # 基础用法 |
7. dict.keys()
, dict.values()
, dict.items()
返回字典视图对象(可迭代)
1 | # 动态字典操作 |
关键特性总结
这些函数均返回的是迭代器,比如map
对象也是返回一个迭代器。
函数 | 返回类型 | 内存效率 | 是否一次性 | 典型应用场景 |
---|---|---|---|---|
map() |
map 对象 |
✅ 高效 | ✅ 是 | 数据转换/批量操作 |
filter() |
filter 对象 |
✅ 高效 | ✅ 是 | 条件筛选/数据清洗 |
zip() |
zip 对象 |
✅ 高效 | ✅ 是 | 多序列合并/矩阵转置 |
enumerate() |
enumerate 对象 |
✅ 高效 | ✅ 是 | 带索引遍历/创建索引映射 |
reversed() |
反向迭代器 | ✅ 高效 | ✅ 是 | 逆序处理/栈操作 |
iter() |
迭代器 | ✅ 高效 | ✅ 是 | 自定义迭代/分块读取 |
dict.views() |
字典视图 | ✅ 动态 | ❌ 可重用 | 字典遍历/实时更新 |
使用注意事项
一次性消耗:这些迭代器大多只能遍历一次
1
2
3mapped = map(str, [1, 2])
list(mapped) # ['1', '2']
list(mapped) # [] 已耗尽惰性求值:元素只在请求时计算
1
2# 不会立即执行所有平方计算
big_squares = map(lambda x: x**2, range(1000000))类型转换:需要持久化结果时转换为容器类型
1
filtered = tuple(filter(lambda x: x > 5, [3, 6, 8]))
内存优势:处理大文件时特别高效
1
2
3
4
5# 仅需少量内存处理大文件
with open('huge.log') as f:
error_lines = filter(lambda line: 'ERROR' in line, f)
for error in error_lines:
process(error)
这些迭代器返回函数是 Python 函数式编程的核心工具,特别适合处理大数据流和构建高效的数据处理管道。
生成器(Generator)
生成器(Generator)是一种特殊的迭代器,它可以在需要时动态生成值,而不是一次性将所有值存储在内存中。生成器使用 yield
关键字来定义生成值的逻辑,每次调用生成器的 __next__()
方法时,它会从上一次的 yield
语句处继续执行,直到遇到下一个 yield
或者函数结束。
生成器在实现上更加简洁和高效,因为它不需要显式地维护整个序列,而是在每次迭代中动态生成下一个值,这种惰性计算的方式使得生成器非常适合处理大数据集或者无限序列。
Python 中有两种定义生成器的方式
生成器函数
使用 def
关键字定义的函数,其中包含 yield
语句来产生值。
1 | def my_generator(): |
生成器表达式
类似于列表推导式,使用圆括号来生成一个生成器。
1 | gen = (x ** 2 for x in range(5)) |
生成器的应用
1. 生成器函数创建的数据
使用 yield
关键字定义的函数返回的对象:
1 | def count_down(n): |
1 | 3 |
2. 生成器表达式创建的数据
使用类似列表推导式但用圆括号 ()
包裹的表达式:
1 | gen = (x**2 for x in range(1, 4)) # 属于生成器 |
生成器的核心特征
惰性计算
只在调用next()
时生成值(不提前计算所有结果)1
2gen = (x for x in range(3))
print(next(gen)) # 0(首次调用时计算)一次性使用
遍历结束后不可复用:1
2
3gen = (x for x in range(2))
list(gen) # [0, 1]
list(gen) # [](已耗尽)内存高效
不存储完整数据集(对比列表推导式):1
2
3import sys
sys.getsizeof([x for x in range(1000000)]) # 一个列表,约 8 MB
sys.getsizeof((x for x in range(1000000))) # 一个娇小的生成器,约 128 Bytes
常见误辨别的非生成器案例
对象类型 | 是否生成器 | 原因 |
---|---|---|
range(5) |
❌ | 返回 range 对象(惰性序列) |
zip([1,2], [3,4]) |
❌ | 返回 zip 对象(迭代器) |
open('file.txt') |
❌ | 返回文件对象(迭代器) |
列表 [x for x in...] |
❌ | 列表推导式返回完整列表对象 |
(x for x in range(5)) |
✅ | 似乎只有这个内置函数返回生成器 |
快速检测方法
1 | import types |
Python面向对象:自定义类分别实现可迭代对象、迭代器、生成器
下面我将设计四个自定义类,分别演示不同迭代特性的实现方式,并提供详细的使用示例:
1. 仅实现 __getitem__
的可迭代对象
1 | class SequenceIterable: |
输出
1 | 1. 下标访问的可迭代对象: |
2. 实现 __iter__
的可迭代对象(非迭代器)
1 | class ClassicIterable: |
输出
1 | -------------------------------------------------- |
3. 同时实现 __iter__
和 __next__
的迭代器
1 | class SquareIterator: |
输出
1 | 3. 自身迭代器: |
4. 生成器类(使用 yield
)
1 | class PrimeGenerator: |
输出
1 | 4. 生成器类 (无限素数): |
类型验证代码
1 | from collections.abc import Iterable, Iterator |
输出
1 | SequenceIterable类型验证: |
关键区别总结:
可迭代对象:
- 实现了
__iter__()
或__getitem__()
- 可通过
iter()
获取迭代器 - 可多次遍历(如
ClassicIterable
)
- 实现了
迭代器:
- 同时实现
__iter__()
和__next__()
__iter__()
返回自身- 一次性使用(如
SquareIterator
)
- 同时实现
生成器:
- 特殊迭代器
- 使用
yield
关键字实现 - 自动维护状态(如
PrimeGenerator
) - 类型为
types.GeneratorType
下标访问对象:
- 仅实现
__getitem__()
- 支持索引和切片
- 可迭代但
isinstance(obj, Iterable)
返回False
- 仅实现
表格总结
Python3 可迭代对象(Iterable)、序列(Sequence)、迭代器(Iterator)、生成器(generator)的关键定义和包含类型:
概念 | 定义 | 包含类型/实现要求 | 核心特性 |
---|---|---|---|
可迭代对象 (Iterable) | 能够一次返回一个成员的对象,支持 for...in 循环遍历 |
序列:list , str , tuple , bytes 非序列: dict , 文件对象自定义类:实现了 __iter__() 或 __getitem__() 方法的类。 |
可通过 iter(obj) 转换为迭代器;isinstance 检测仅对实现 __iter__() 方法的有效 |
序列 (Sequence) | 可迭代对象的子集,支持高效整数索引访问和长度获取 | list , str , tuple , bytes |
必须实现:__getitem__() (索引访问)__len__() (长度获取)注意: dict 不是序列 |
迭代器 (Iterator) | 表示数据流的对象,通过 next() 逐个返回元素,耗尽后抛出 StopIteration |
内置转换:iter(可迭代对象) (如 list_iterator )自定义类:同时实现 __iter__() (返回自身)和 __next__() 方法 |
一次性消费(遍历后不可复用) 迭代器本身也是可迭代对象。 |
生成器 (Generator) | 特殊的迭代器,由包含 yield 的函数或生成器表达式创建 |
生成器函数:def gen(): yield ... 生成器表达式: (x for x in range(n)) |
惰性求值(按需生成值) 继承迭代器的所有特性 |
关键特性:
包含关系 :生成器、迭代器、序列均属于可迭代对象。
生成器 ⊂ 迭代器 ⊂ 可迭代对象
序列 ⊂ 可迭代对象转换关系:
- 可迭代对象 → 迭代器:
iter(可迭代对象)
- 序列 → 迭代器:
iter(序列)
(如iter([1,2,3])
)
- 可迭代对象 → 迭代器:
判断方法:
- 可迭代对象:
iter(obj)
不报错即为可迭代(最可靠) - 迭代器:
isinstance(obj, Iterator)
且实现__next__()
- 生成器:
isinstance(obj, types.GeneratorType)
- 可迭代对象:
⚠️ 注意:
- 仅实现
__getitem__()
的类是可迭代对象,但isinstance(obj, Iterable)
返回False
。- 迭代器必须同时实现
__iter__()
(返回自身)和__next__()
才能被正确识别。- 生成器是语法糖,本质是实现了
__iter__()
和__next__()
的迭代器。
参考文献:
Python详解可迭代对象(Iterable)、序列(Sequence)、迭代器(Iterator)、生成器(generator)_可迭代序列-CSDN博客
【Python入门第十三讲】可迭代对象(Iterable)、迭代器(Iterator)和生成器(Generator)-腾讯云开发者社区-腾讯云