2.16 迭代器与可迭代对象
2.16.1 迭代器的概念
2.16.1.1 迭代器与可迭代对象的区别
# 可迭代对象是可以被迭代的对象,比如列表、元组、字符串等
iterable = [1, 2, 3]
# 迭代器是一个有迭代状态的对象,可以一一产生可迭代对象的元素
iterator = iter(iterable)
# 迭代器可以从可迭代对象获得
print(isinstance(iterable, Iterable)) # True,因为列表是可迭代对象
print(isinstance(iterator, Iterator)) # True,因为iter函数返回迭代器
输出:
True
True
解释: 可迭代对象有一个__iter__()方法,返回一个迭代器。迭代器有一个__next__()方法,用于返回下一个元素。
2.16.1.2 iter()与next()函数的工作原理
# iter()函数接受一个可迭代对象,并返回一个迭代器
my_list = [1, 2, 3]
my_iter = iter(my_list)
# next()函数接受一个迭代器,并返回它的下一个元素
print(next(my_iter)) # 输出 1
print(next(my_iter)) # 输出 2
输出:
1
2
解释: iter()函数获取对象的迭代器,next()函数从迭代器中获取下一个元素。
2.16.1.3 实现迭代器协议的要求(__iter__()与__next__())
class MyIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index < len(self.data):
result = self.data[self.index]
self.index += 1
return result
else:
raise StopIteration
# 使用自定义迭代器
my_data = [1, 2, 3]
my_custom_iterator = MyIterator(my_data)
for item in my_custom_iterator:
print(item)
输出:
1
2
3
解释: 自定义迭代器必须实现__iter__()返回迭代器自身,__next__()返回下一个元素,当没有元素时抛出StopIteration。
2.16.1.4 使用迭代器简化数据遍历
# 使用迭代器遍历数据
my_iter = iter([1, 2, 3])
for num in my_iter:
print(num)
输出:
1
2
3
解释: 迭代器允许我们逐个访问元素,而不需要关心数据的具体结构。
2.16.2 创建可迭代对象
2.16.2.1 可迭代对象的定义
# 可迭代对象定义为有一个__iter__()方法的对象
my_list = [1, 2, 3]
print(hasattr(my_list, '__iter__')) # 输出 True
输出:
True
解释: 列表等内置类型都是可迭代对象。
2.16.2.2 实现可迭代对象协议的要求(__iter__()方法)
class MyIterable:
def __iter__(self):
return iter([1, 2, 3])
my_iterable = MyIterable()
for item in my_iterable:
print(item)
输出:
1
2
3
解释: 可迭代对象需要实现__iter__()方法,返回一个迭代器。
2.16.2.3 使用for循环遍历可迭代对象
# for循环本质上是在使用迭代器
for char in "批量小王子":
print(char)
输出:
批
量
小
王
子
解释: for循环自动调用__iter__()和__next__()。
2.16.2.4 自定义可迭代对象的实现
class MyCollection:
def __init__(self, elements):
self.elements = elements
def __iter__(self):
for elem in self.elements:
yield elem
my_collection = MyCollection([1, 2, 3])
for elem in my_collection:
print(elem)
输出:
1
2
3
解释: 自定义可迭代对象通过yield实现__iter__()。
2.16.2.5 可迭代对象的内存效率与优化
# 可迭代对象可以节省内存,因为它不需要一次性将所有元素加载到内存
class LazyRange:
def __init__(self, start, stop):
self.start = start
self.stop = stop
def __iter__(self):
current = self.start
while current < self.stop:
yield current
current += 1
# 使用懒加载范围
for num in LazyRange(0, 1000000):
if num > 100: # 只处理前100个数字
break
输出:
0
1
...
100
解释: 懒加载可迭代对象可以节省内存,因为它不需要一次性创建所有元素。
2.16.3 内置函数iter()和next()的使用
2.16.3.1 iter()函数的用法与实现
# iter()函数用法
my_iterable = [1, 2, 3]
my_iterator = iter(my_iterable)
print(next(my_iterator)) # 输出 1
输出:
1
2.16.3.2 next()函数的用法与错误处理(如StopIteration)
# next()函数用法和错误处理
my_iterator = iter([1, 2, 3])
try:
print(next(my_iterator))
print(next(my_iterator))
print(next(my_iterator))
print(next(my_iterator)) # 将抛出StopIteration
except StopIteration:
print("没有更多元素")
输出:
1
2
3
没有更多元素
2.16.3.3 使用next()遍历迭代器中的元素
# 使用next()遍历元素
my_iterator = iter([1, 2, 3])
while True:
try:
print(next(my_iterator))
except StopIteration:
break
输出:
1
2
3
2.16.3.4 next()与for循环的关系
# for循环内部使用next()
for elem in [1, 2, 3]:
print(elem)
输出:
1
2
3
解释: for循环内部会调用iter()获取迭代器,然后不断调用next()直到抛出StopIteration。
这些代码示例提供了迭代器和可迭代对象的概念、创建和使用,以及iter()和next()函数的详细说明。您可以在本地环境中执行这些代码来验证输出。