一、迭代器和可迭代对象
1.可迭代对象
可迭代对象指可以通过for循环遍历的对象,包括列表、元组、字典、集合等。
lst=[1,2,3,4,5]
for i in lst:
print(i)
列表可以用迭代器遍历,说明它是一个可迭代对象
2.迭代器
从语法结构上讲,迭代器是一个可以记住遍历位置的对象(类)。从实现功能上讲,迭代器是一个特殊的可迭代对象。迭代器必须包含__iter__()方法和__next__()方法,这在下面会详细介绍。
3.迭代器和可迭代对象的关系
迭代器一定是一个可迭代对象;可迭代对象不一定是一个迭代器。
4.迭代器和可迭代对象的差异
迭代器能够按需在内存中生成下一个元素,而不会一次性生成所有元素。这在处理大型数据集或无限序列时非常有用。
而可迭代对象,如列表和元组等,在进入for循环进行遍历时会把所有元素载入内存空间,这无疑会浪费内存。
二、如何实现一个迭代器
1.必须包含的方法
迭代器对象必须实现两个方法:
__iter__()方法:返回迭代器对象本身。
__next__()方法:返回可迭代对象的下一个元素,并在没有元素可迭代时引发 StopIteration 异常。
下面是实现python迭代器的例子:
class Myiterator:
def __init__(self,data):
self.data=data
self.index=0
self.length=len(data)
def __iter__(self):
return self
def __next__(self):
if self.index<self.length:
value=self.data[self.index]
self.index+=1
return value
else:
raise StopIteration
lst=[1,2,3,4,5]
test=Myiterator(lst)
for i in test:
print(i)
输出结果:
1
2
3
4
5
在上面的示例中,我们定义了一个名为 MyIterator 的迭代器类。该类包含__iter__()方法和__next__()方法。前者返回迭代器对象本身,而后者则根据索引逐个返回可迭代对象的元素。
需要注意的是,一旦迭代器遍历完所有元素,再次调用__next__()方法将引发 StopIteration 异常。为了更安全地使用迭代器,我们通常会使用for循环来遍历可迭代对象,它会自动处理 StopIteration 异常并停止迭代过程。
2.python如何识别迭代器
根据迭代器协议,一旦类中定义了__iter__()方法和__next__()方法,并且方法名正确,python就会把这个类视为迭代器类。
需要注意的是,除了这两个方法,迭代器还可以实现其他方法,例如__iter__()方法用于初始化迭代器对象。但是,无论迭代器实现了哪些其他方法,只要它实现了__iter__()方法和__next__()方法,并且方法名正确,就可以被认为是迭代器。
三、实现迭代器的其他两种方法
1.利用内置函数iter
这里的iter不是我们定义的迭代器类的类方法,而是一个python内置函数。iter函数会获取可迭代对象,然后自动生成迭代器,并且同样拥有__next__()方法,同样可以用for循环进行迭代!
lst=[1,2,3,4,5]
lst_iter=iter(lst)
print(next(lst_iter))
print(next(lst_iter))
print(next(lst_iter))
输出:
1
2
3
lst=[1,2,3,4,5]
lst_iter=iter(lst)
for i in lst_iter:
print(i)
输出:
1
2
3
4
5
你可以将它理解为我们所自定义的迭代器类的自动版!
2.利用yield关键字
yield关键字可以视为人工断点,每次迭代到yield时,返回yield后的返回值,并暂停函数运行,进行新一轮迭代:
def my_generator():
yield 1
yield 2
yield 3
gen = my_generator()
print(next(gen)) # 输出:1
print(next(gen)) # 输出:2
print(next(gen)) # 输出:3
def my_generator():
yield 1
yield 2
yield 3
gen=my_generator()
for i in gen:
print(i)
上述两端代码,结果均为:
1
2
3
函数使用yield时,也相当于返回了一个迭代器对象。可以利用next方法,也可以进行for循环。只不过,yield后的变量值代表的是迭代器每次返回的值,而不是函数返回的值。
因此,利用for循环和yield关键字,也可以实现一个迭代器:
import random
def other_iterator()->iter:
date=[random.randint(1,9) for i in range(5)]
for i in range(5):
yield date[i]
gen=other_iterator()
for i in gen:
print(i)