Python中迭代器与可迭代对象对比与区别
可迭代对象(Iterable)
什么是可迭代对象?
可迭代对象是指实现了__iter__()方法的对象,或者实现了一个能够返回迭代器的__getitem__()方法的对象。简单来说,可迭代对象可以通过for循环遍历,或者通过内置函数iter()将其转换为迭代器。常见的可迭代对象包括:
- 序列类型:如list(列表)、tuple(元组)、str(字符串)、range(范围对象)
- 集合类型:如set(集合)、frozenset(冻结集合)
- 字典类型:如dict(字典)
- 文件对象:如打开的文件(文件句柄)
- 以及其他自定义实现了__iter__()或__getitem__()方法的对象
如何判断一个对象是否是可迭代对象?
可以使用collections.abc模块中的Iterable类来判断一个对象是否是可迭代对象:
from collections.abc import Iterable
print(isinstance([1, 2, 3], Iterable)) # True
print(isinstance("hello", Iterable)) # True
print(isinstance(123, Iterable)) # False
可迭代对象的特点
- 实现了__iter__()方法:当调用iter(obj)时,iter()方法返回一个迭代器对象(即实现了__next__()方法的对象)。
- 可以使用for循环遍历:for item in obj的背后就是在不断调用该对象的迭代器对象的__next__()方法。
- 支持多次迭代:每次调用iter()方法时,它都会返回一个新的迭代器,从而可以多次遍历。
# 列表是可迭代对象,可以多次迭代
my_list = [1, 2, 3]
for item in my_list:
print(item) # 输出1, 2, 3
for item in my_list:
print(item) # 再次输出1, 2, 3
迭代器
什么是迭代器?
迭代器是一个实现了__iter__()和__next__()方法的对象。迭代器与可迭代对象的区别在于,迭代器本身就是一个状态ful的对象,它可以逐个获取数据元素,而不像可迭代对象那样可以随时重置。迭代器的特点是:
- 实现了__next__()方法:每次调用该方法时,它会返回下一个数据元素;如果没有更多元素,它会引发StopIteration异常。
- 只能被遍历一次:一旦元素被迭代完毕,再次调用__next__()就会直接引发StopIteration异常
如何判断一个对象是否是迭代器?
我们可以使用collections.abc模块中的Iterator类来判断一个对象是否是迭代器:
from collections.abc import Iterator
my_iter = iter([1, 2, 3]) # 通过iter()将列表转化为迭代器
print(isinstance(my_iter, Iterator)) # True
print(isinstance([1, 2, 3], Iterator)) # False
迭代器的特点
- 实现了__iter__()方法,并且__iter__()返回自身。
- 实现了__next__()方法,该方法会返回迭代器的下一个元素。
- 状态ful:迭代器是有状态的对象,它记录了当前的遍历位置,一旦遍历完成就无法再次遍历。
# 使用迭代器
my_iter = iter([1, 2, 3])
print(next(my_iter)) # 输出 1
print(next(my_iter)) # 输出 2
print(next(my_iter)) # 输出 3
# print(next(my_iter)) # 再次调用会引发StopIteration异常
迭代器与可迭代对象的区别
- 实现的接口不同:
- 可迭代对象必须实现__iter__()方法。
- 迭代器必须实现__iter__()和__next__()方法
- 返回值不同:
- 调用iter()方法时,可迭代对象会返回一个新的迭代器对象。
- 迭代器的__iter__()方法返回自身。
- 是否能够重复遍历:
- 可迭代对象通常支持多次遍历,因为每次调用iter()都会生成一个新的迭代器。
- 迭代器只能遍历一次,因为它在内部维护了当前遍历的状态,一旦遍历完毕就无法重置。
- 数据消耗特性:
- 可迭代对象中的数据元素不会在遍历中被“消耗”。
- 迭代器中的数据元素在遍历后被“消耗”掉,不可再次访问。
可迭代对象与迭代器的关系
所有的迭代器都是可迭代对象(因为迭代器也实现了__iter__()方法),但是并不是所有的可迭代对象都是迭代器。
如何自定义可迭代对象与迭代器?
自定义可迭代对象
要创建一个自定义的可迭代对象,我们需要在类中实现__iter__()方法。iter()方法应该返回一个迭代器对象。
class MyIterable:
def __init__(self, data):
self.data = data
def __iter__(self):
return iter(self.data)
# 使用自定义的可迭代对象
my_iterable = MyIterable([1, 2, 3])
for item in my_iterable:
print(item)
自定义迭代器
要创建一个自定义的迭代器,我们需要在类中实现__iter__()和__next__()方法。next()方法应该返回下一个数据元素,并在迭代结束时引发StopIteration异常。
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):
value = self.data[self.index]
self.index += 1
return value
else:
raise StopIteration
# 使用自定义的迭代器
my_iterator = MyIterator([1, 2, 3])
for item in my_iterator:
print(item)
总结
- **可迭代对象(Iterable)**是能够返回迭代器的对象,常见的序列类型(如list、tuple、str)、集合类型、字典类型都是可迭代对象。
- **迭代器(Iterator)**是可以逐个访问元素的对象,它实现了__next__()方法和__iter__()方法。
- 迭代器和可迭代对象的关系是:**所有迭代器都是可迭代对象,但并非所有可迭代