迭代器和生成器
迭代器和生成器
简单理解,可以一个个读取操作的对象,称为可迭代对象。可迭代对象就是你能用for循环迭代它的元素,迭代器是指可以用next()获取它的下一个值。生成器依赖于迭代器,在Python中,一边迭代(循环)一边计算的机制,称为生成器。生成器能够迭代的关键是因为它有一个__next__方法,因此生成器首先得是一个迭代器,每迭代一次,生成一个元素。
迭代器
Python 3.12.7 (main, Nov 8 2024, 17:55:36) [GCC 14.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> l = ['a','b','c']
>>> for i in l:
... print(i)
...
a
b
c
>>> i = iter(l)
>>> next(i)
'a'
>>> next(i)
'b'
>>> next(i)
'c'
>>> i = l.__iter__()
>>> i.__next__()
'a'
>>> i.__next__()
'b'
>>> i.__next__()
'c'
>>> i.__next__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
自定义迭代器的代码
#!/usr/bin/env python
class Test:
def __init__(self,a,b):
self.a = a
self.b = b
def __iter__(self):
return self
def __next__(self):
self.a += 1
if self.a > self.b:
raise StopIteration
return self.a
test = Test(0,10)
print(next(test))
print(next(test))
print(next(test))
print(next(test))
print(next(test))
print(next(test))
print(next(test))
print(next(test))
print(next(test))
print(next(test))
print(next(test))
print(next(test))
运行结果
┌──(root㉿kali)-[~/python_code/python_4]
└─# python iteration.py
1
2
3
4
5
6
7
8
9
10
Traceback (most recent call last):
File "/root/python_code/python_4/iteration.py", line 29, in <module>
print(next(test))
^^^^^^^^^^
File "/root/python_code/python_4/iteration.py", line 14, in __next__
raise StopIteration
StopIteration
生成器
Python 3.12.7 (main, Nov 8 2024, 17:55:36) [GCC 14.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> g = (x**x for x in range(1,4))
>>> g
<generator object <genexpr> at 0x7f66f2e26cf0>
>>> for x in g:
... print(x)
...
1
4
27
>>>
斐波那契数列
#!/usr/bin/env python
def fib(n):
current = 0
a,b = 1,1
while current < n:
yield a
a,b = b,a+b
current += 1
f5 = fib(5)
for i in f5:
print(i)
运行结果
┌──(root㉿kali)-[~/python_code/python_4]
└─# python Fibonacci.py
1
1
2
3
5
详解迭代器和生成器(了解)
Python迭代器是Python中用于遍历数据集合的重要工具,它允许我们以高效、灵活的方式访问数据集合中的元素。以下是关于Python迭代器的详细解析。
1. 迭代器的基本概念
1.1 可迭代对象(Iterable)
- 定义:内部实现了
__iter__()方法的对象,返回一个迭代器对象。常见的可迭代对象包括列表、元组、集合、字典、字符串等。(注意:字典不能被直接迭代,需要用items()转换) - 特点:
- 可以使用
for循环直接遍历。 - 通过
iter()函数可以将其转换为迭代器。
- 可以使用
1.2 迭代器(Iterator)
- 定义:内部实现了
__iter__()和__next__()方法的对象。__iter__():返回迭代器对象本身。__next__():返回下一个元素,若没有元素则抛出StopIteration异常。
- 特点:
- 惰性计算:按需生成数据,适合处理大数据集。
- 状态保存:记录当前遍历的位置,只能单向前进。
- 一次性消耗:迭代器遍历完成后不可逆,需重新生成。
2. 迭代器的工作原理
2.1 如何使用迭代器?
-
手动使用
iter()和next()
将可迭代对象转换为迭代器后,通过next()逐个获取元素:numbers = [1, 2, 3] iterator = iter(numbers) # 转换为迭代器 print(next(iterator)) # 输出: 1 print(next(iterator)) # 输出: 2 print(next(iterator)) # 输出: 3 # print(next(iterator)) # 抛出 StopIteration 异常 -
结合
try-except处理异常
手动控制迭代过程时,需捕获StopIteration异常:import sys my_list = [1, 2, 3] iterator = iter(my_list) while True: try: print(next(iterator)) except StopIteration: sys.exit()
2.2 for 循环的本质
for 循环内部自动处理了迭代器的创建和异常捕获:
for item in [1, 2, 3]:
print(item)
等价于:
it = iter([1, 2, 3])
while True:
try:
item = next(it)
print(item)
except StopIteration:
break
3. 自定义迭代器
通过实现 __iter__() 和 __next__() 方法,可以创建自定义迭代器。例如,生成一个数字序列:
class MyRange:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current < self.end:
num = self.current
self.current += 1
return num
else:
raise StopIteration
# 使用自定义迭代器
for i in MyRange(1, 4):
print(i) # 输出: 1 2 3
4. 生成器(Generator)
生成器是迭代器的简化版本,通过 yield 关键字实现,适合生成大规模数据或无限序列。
4.1 生成器函数
def count_down(start):
current = start
while current > 0:
yield current # 暂停并返回当前值
current -= 1
gen = count_down(3)
for num in gen:
print(num) # 输出: 3 2 1
4.2 生成器表达式
类似列表推导式,但使用圆括号:
gen = (x * x for x in range(3))
for num in gen:
print(num) # 输出: 0 1 4
4.3 生成器的高级用法
-
惰性求值:适合处理大文件或无限序列。
def read_large_file(file_path): with open(file_path) as f: for line in f: yield line.strip() -
send()、throw()、close():send(value):向生成器内部传递值。throw(exception):抛出异常。close():强制结束生成器。
5. 生成器的应用场景
5.1 处理大数据
-
节省内存:生成器不会一次性加载所有数据到内存。
def read_file_line_by_line(file_path): with open(file_path) as f: for line in f: yield line.strip()
5.2 无限序列
-
生成器处理无限序列:
def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b for num in fibonacci(): if num > 100: break print(num) # 输出斐波那契数列直到100
5.3 自定义复杂迭代逻辑
- 分页数据加载、过滤条件动态调整等场景。
6. 迭代器与生成器的优缺点
| 特性 | 迭代器 | 生成器 |
|---|---|---|
| 实现方式 | 需手动实现 __iter__ 和 __next__ |
使用 yield 自动实现 |
| 内存占用 | 节省内存(惰性计算) | 节省内存(按需生成) |
| 代码简洁性 | 需编写类和方法 | 代码更简洁 |
| 适用场景 | 需要严格控制迭代逻辑 | 简单数据生成或无限序列 |
7. 常见问题
7.1 为什么迭代器只能单向遍历?
迭代器的设计原则是“单向性”,即只能从前往后遍历,且遍历完成后无法重置。若需重复使用,需重新生成迭代器。
7.2 如何判断对象是否是迭代器?
使用 collections.abc.Iterator 判断:
from collections.abc import Iterator
print(isinstance(iter([1, 2, 3]), Iterator)) # True
7.3 列表推导式 vs 生成器表达式
-
列表推导式:一次性生成所有数据,占用内存。
squares = [x * x for x in range(1000000)] -
生成器表达式:按需生成数据,节省内存。
squares = (x * x for x in range(1000000))
8. 总结
- 迭代器是Python中统一的遍历机制,适用于所有可迭代对象。
- 生成器是迭代器的简化形式,通过
yield实现惰性计算。 - 应用场景:大数据处理、无限序列、内存优化等。
- 核心优势:节省内存、代码简洁、灵活控制迭代逻辑。
通过掌握迭代器和生成器,可以编写更高效、优雅的Python代码,尤其是在处理大规模数据或复杂迭代逻辑时。
浙公网安备 33010602011771号