Python 的可迭代对象、迭代器对象与生成器
一、可迭代对象 (Iterable)
定义:任何实现了__iter__()方法的对象,或者实现了__getitem__()方法且参数从0开始索引的对象
特点:可以被用于for循环,可以使用iter()函数获取其迭代器
# 常见的可迭代对象
my_list = [1, 2, 3] # 列表
my_tuple = (1, 2, 3) # 元组
my_string = "hello" # 字符串
my_dict = {"a": 1, "b": 2} # 字典
my_set = {1, 2, 3} # 集合
# 使用for循环遍历
for item in my_list:
print(item)
# 使用iter()函数
iter_obj = iter(my_list) # 等同于 my_list.__iter__()
print(next(iter_obj)) # 等同于 iter_obj.__next__()
print(next(iter_obj))
print(next(iter_obj))
二、迭代器对象 (Iterator)
定义:实现了__iter__()和__next__()方法的对象
特点:迭代器本身也是可迭代对象,每次调用next()会返回下一个值,耗尽后会抛出StopIteration异常
适用场景:需要自定义复杂遍历逻辑的场景
# 自定义迭代器
class MyIterator:
def __init__(self, max_value):
self.max_value = max_value
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current < self.max_value:
self.current += 1
return self.current - 1
else:
raise StopIteration
# 使用自定义迭代器
my_iter = MyIterator(5)
print(next(my_iter)) # 0
print(next(my_iter)) # 1
print(next(my_iter)) # 2
# 或者用for循环
for num in MyIterator(3):
print(num) # 0, 1, 2
示例1:自定义数字范围迭代器
class NumberRange:
"""自定义数字范围迭代器"""
def __init__(self, start, end, step=1):
self.current = start
self.end = end
self.step = step
def __iter__(self):
return self
def __next__(self):
if self.current >= self.end:
raise StopIteration
current_value = self.current
self.current += self.step
return current_value
# 使用迭代器
print("数字范围迭代器:")
numbers = NumberRange(1, 6) # 1到5
for num in numbers:
print(num, end=" ") # 输出: 1 2 3 4 5
#简化版
def my_range(start, stop, step=1):
while start < stop:
yield start
start += step
for i in my_range(1,5,2): # 1 3
print(i)
三、生成器 (Generator)
定义:使用yield关键字或生成器表达式创建的特殊迭代器
特点:懒加载,按需生成值,内存效率高,执行到yield时暂停,下次从暂停处继续
适用场景:适合简单的数据流处理、懒加载和内存敏感的场景
3.1 生成器函数
def countdown(n):
"""生成器函数示例"""
print("开始倒计时")
while n > 0:
yield n
n -= 1
print("发射!")
# 使用生成器
cd = countdown(5)
print(cd) #实际指向了内存地址,并不存储真实数据 <generator object countdown at 0x000001CF42EEE2C0>
print(next(cd)) # 5
print(next(cd)) # 4
print(next(cd)) # 3
# 或者用for循环
for num in countdown(3):
print(num) # 3, 2, 1
3.2 生成器表达式
# 类似于列表推导式,但使用圆括号
squares = (x*x for x in range(5)) # 类别生成式格式为 [x*x for x in range(5)] ,注意没有元组生成式,因为()给了生成器
print(next(squares)) # 0
print(next(squares)) # 1
print(next(squares)) # 4
# 或者转换为列表
result = list(squares)
print(result) # [9, 16]
使用场景和示例
场景1:处理大型数据集(内存优化)
python
def read_large_file(file_path):
"""逐行读取大文件,避免内存溢出"""
with open(file_path, 'r', encoding='utf-8') as file:
for line in file:
yield line.strip()
# 使用示例
for line in read_large_file('large_data.txt'):
# 处理每一行数据
if 'error' in line:
print(line)
场景2:简单的计数器生成器
python
def simple_counter(limit):
"""简单的计数器生成器"""
count = 1
while count <= limit:
yield count
count += 1
# 使用生成器
print("\n计数器生成器:")
counter = simple_counter(5)
for num in counter:
print(num, end=" ") # 输出: 1 2 3 4 5
"一劳永逸" 的话,有是有的,而 "一劳永逸" 的事却极少