iter()
是 Python 的内置函数,用于创建迭代器对象。它是 Python 迭代协议的核心组成部分,负责将可迭代对象转换为迭代器。
一、基本概念
1. 可迭代对象 (Iterable)
- 实现了
__iter__()
方法的对象 - 可以通过
iter()
函数转换为迭代器 - 常见可迭代对象:列表、元组、字符串、字典、集合、文件对象等
2. 迭代器 (Iterator)
- 实现了
__iter__()
和__next__()
方法的对象 __iter__()
返回自身__next__()
返回下一个元素,没有元素时抛出StopIteration
异常
迭代协议
Python 的迭代协议由两个方法组成:
__iter__()
: 返回迭代器对象__next__()
: 返回下一个元素
二、iter()
函数语法
1. 单参数形式
iter(iterable) -> iterator
- 参数:可迭代对象
- 返回:迭代器对象
2. 双参数形式
iter(callable, sentinel) -> iterator
- 参数1:可调用对象(函数、方法等)
- 参数2:哨兵值(特殊标记值)
- 返回:迭代器对象,直到返回值等于哨兵值
三、工作原理
1. 调用过程
# 当使用 for 循环时
for item in my_object:
# 处理 item
# 等价于
iterator = iter(my_object) # 调用 my_object.__iter__()
while True:
try:
item = next(iterator) # 调用 iterator.__next__()
# 处理 item
except StopIteration:
break
方法解析
iter(obj)
调用obj.__iter__()
next(iterator)
调用iterator.__next__()
四、使用示例
1. 基本用法
# 列表迭代
numbers = [1, 2, 3]
num_iter = iter(numbers)
print(next(num_iter)) # 1
print(next(num_iter)) # 2
print(next(num_iter)) # 3
print(next(num_iter)) # StopIteration
# 字符串迭代
text = "Python"
char_iter = iter(text)
print(next(char_iter)) # 'P'
print(next(char_iter)) # 'y'
2. 哨兵值用法
import random
def random_number():
return random.randint(1, 100)
# 创建迭代器:当随机数为42时停止
rand_iter = iter(random_number, 42)
for num in rand_iter:
print(num)
# 输出随机数直到出现42
3. 文件处理
# 逐行读取文件直到空行
with open('data.txt') as f:
for line in iter(f.readline, ''):
print(line.strip())
4. 支持迭代协议
class MyIterable:
def __iter__(self):
return iter([10, 20, 30])
obj = MyIterable()
for item in obj: # 隐式调用 iter(obj)
print(item) # 10, 20, 30
5. 自定义迭代器
class Counter:
def __init__(self, max):
self.max = max
self.count = 0
def __iter__(self):
return self # 返回自身作为迭代器
def __next__(self):
if self.count < self.max:
self.count += 1
return self.count
raise StopIteration
counter = Counter(3)
for num in counter: # 等价于 for num in iter(counter)
print(num) # 1, 2, 3
6. 生成器作为迭代器
def countdown_gen(n):
while n > 0:
yield n
n -= 1
# 生成器本身就是迭代器
counter = countdown_gen(3)
print(next(counter)) # 3
print(next(counter)) # 2
print(next(counter)) # 1
print(next(counter)) # StopIteration
六、特殊用法
1. 双参数形式:哨兵值迭代
import random
def random_number():
return random.randint(1, 100)
# 当返回值为 42 时停止
iterator = iter(random_number, 42)
for num in iterator:
print(num) # 打印随机数直到出现 42
2. 文件迭代
# 逐行读取文件
with open('data.txt') as f:
for line in iter(f.readline, ''): # 空行停止
print(line)
3. 无限迭代
from itertools import count
# 无限迭代器
infinite = iter(count(1), None) # 永不停止
for i in infinite:
if i > 5: break
print(i) # 1,2,3,4,5
七、迭代器 vs 可迭代对象
特性 | 可迭代对象 | 迭代器 |
---|---|---|
定义 | 实现 __iter__() | 实现 __iter__() 和 __next__() |
状态 | 无状态 | 有状态(记录当前位置) |
重用 | 可多次迭代 | 单次使用(耗尽后需重置) |
创建 | 容器对象(list, dict等) | iter() 函数或自定义类 |
示例 | [1,2,3] , range(10) | iter([1,2,3]) , open('file.txt') |
八. 常见错误与陷阱
错误1:尝试迭代非可迭代对象
num = 42
try:
iter(num)
except TypeError as e:
print(e) # 'int' object is not iterable
错误2:多次迭代同一个迭代器
numbers = [1, 2, 3]
iterator = iter(numbers)
list(iterator) # [1, 2, 3]
list(iterator) # [] 迭代器已耗尽
错误3:误解双参数形式
# 错误用法
try:
iter([1,2,3], None) # TypeError: iter(v, w): v must be callable
except TypeError as e:
print(e)
九、性能考虑
1. 内存效率
# 迭代器 vs 列表
large_data = range(10**6) # 不占用实际内存
# 使用迭代器
iterator = iter(large_data)
for _ in range(10):
next(iterator) # 只处理前10个元素
# 使用列表
list_data = list(large_data) # 占用大量内存
2. 速度比较
import timeit
# 列表迭代
list_time = timeit.timeit(
'for i in data: pass',
'data = list(range(10000))',
number=1000
)
# 迭代器迭代
iter_time = timeit.timeit(
'iterator = iter(data); next(iterator)',
'data = range(10000)',
number=1000
)
print(f"列表迭代: {list_time:.6f}秒")
print(f"迭代器迭代: {iter_time:.6f}秒")
十、最佳实践
1. 正确实现迭代协议
class GoodIterator:
def __iter__(self):
# 每次返回新的迭代器
return iter([1, 2, 3])
class BadIterator:
def __iter__(self):
# 错误:返回自身但未实现 __next__
return self
2. 使用生成器简化
def batch_generator(data, batch_size):
"""生成器实现批处理"""
for i in range(0, len(data), batch_size):
yield data[i:i+batch_size]
# 使用
data = list(range(100))
for batch in batch_generator(data, 10):
print(batch)
3. 处理大型数据集
def large_dataset():
"""生成大型数据集(惰性)"""
for i in range(1000000):
yield i
# 高效处理
processor = BatchProcessor(large_dataset(), batch_size=1000)
for batch in processor:
process(batch)
4. 避免常见错误
# 错误:尝试多次迭代同一个迭代器
iterator = iter([1,2,3])
list(iterator) # [1,2,3]
list(iterator) # [] 已耗尽
# 正确:每次创建新迭代器
data = [1,2,3]
list(iter(data)) # [1,2,3]
list(iter(data)) # [1,2,3]
总结
iter()
函数是 Python 迭代机制的核心:
- 转换可迭代对象:将列表、字符串等转换为迭代器
- 支持哨兵值:创建基于条件的迭代器
- 实现惰性求值:按需生成数据,节省内存
- 统一迭代接口:使各种容器对象支持一致的迭代方式
关键知识点:
- 可迭代对象必须实现
__iter__()
方法 - 迭代器必须实现
__iter__()
和__next__()
方法 iter()
调用__iter__()
方法next()
调用__next__()
方法- 迭代器只能使用一次,耗尽后需重新创建
何时使用 iter()
:
- 处理大型数据集(避免内存溢出)
- 需要部分迭代(不处理所有元素)
- 创建自定义迭代行为
- 实现惰性求值逻辑
- 处理无限序列
理解 iter()
的工作原理是掌握 Python 迭代机制的关键,它使您能够高效处理各种数据源,从内存中的小列表到磁盘上的大型文件流。