python3 迭代器
可迭代(Iterable)对象与迭代器(Iterator)
可迭代对象
凡是可以返回一个迭代器的对象都可称之为可迭代对象。
判断对象是否Iterable:
from collections import Iterable
print(isinstance([],Iterable)) #True
print(isinstance((),Iterable)) #True
print(isinstance({},Iterable)) #True
print(isinstance('ABC',Iterable)) #True
print(isinstance((x for x in range(10)),Iterable)) #True
print(isinstance(100,Iterable))#False
迭代器
迭代是Python最强大的功能之一,是访问集合元素的一种方式。
任何实现了__iter__
和__next__()
方法的对象都是迭代器,__iter__
返回迭代器自身,__next__
返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常。
- 迭代器是一个可以记住遍历的位置的对象。
- 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
- 迭代器只能往前不会后退。
- 迭代器有两个基本的方法:iter() 和 next()。
- 生成器一定是迭代器(反之不成立)
可以使用迭代器进行访问的对象:
-
序列:字符串、列表、元组
-
非序列:字典、文件
-
自定义类:用户自定义的类实现了__iter__()或__getitem__()方法的对象
判断对象是否是Iterator:
from collections import Iterator
print(isinstance((x for x in range(10)),Iterator)) #True
print(isinstance([],Iterator)) #False
print(isinstance({},Iterator)) #False
print(isinstance('abc', Iterator)) #False
生成器都是 Iterator 对象,但 list、 dict、 str 虽然是 Iterable,却不是Iterator。
把Iterable对象变成 Iterator:
from collections import Iterator
print(isinstance(iter([]),Iterator)) #True
print(isinstance(iter('ABC'),Iterator)) #True
访问迭代器中的元素
使用next()访问
使用next()函数输出迭代器中的下一个值,没有更多的元素时,抛出StopIteration 的错误。
list=[1,2,3,4]
it = iter(list) # 创建迭代器对象
print (next(it))
print (next(it))
print (next(it))
print (next(it))
print (next(it))
输出:
1
2
3
4
Traceback (most recent call last):
File "E:/ru/231n/exer.py", line 7, in <module>
print (next(it))
StopIteration
这是因为 Python 的 Iterator 对象表示的是一个数据流, Iterator 对象可以被 next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration 错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过 next()函数实现按需计算下一个数据,所以 Iterator 的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator 甚至可以表示一个无限大的数据流,例如全体自然数。而使用list 是永远不可能存储全体自然数的。
使用for语句访问
使用for语句遍历,这样就不需要关心 StopIteration 的错误。
list=[1,2,3,4]
it = iter(list) # 创建迭代器对象
for x in it:
print (x, end=" ") #1 2 3 4
创建一个迭代器
把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__() 与 __next__() 。
__iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__() 方法并通过 StopIteration 异常标识迭代的完成。
__next__() 方法会返回下一个迭代器对象。
创建一个返回数字的迭代器,初始值为 1,逐步递增 1:
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
x = self.a
self.a += 1
return x
myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter)) #1
print(next(myiter)) #2
print(next(myiter)) #3
print(next(myiter)) #4
print(next(myiter)) #5
StopIteration
StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 __next__() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。
在 20 次迭代后停止执行:
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 20:
x = self.a
self.a += 1
return x
else:
raise StopIteration
myclass = MyNumbers()
myiter = iter(myclass)
for x in myiter:
print(x)
输出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20