Python編程技術:迭代器Iterator和可迭代對象Iterable
可迭代對象Iterable
可迭代對象
:凡是可以返回一個迭代器的對象都可稱之爲可迭代對象。
判斷對象是否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
迭代器Iterator
迭代是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
。
這是因爲 Python 的 Iterator
對象表示的是一個數據流
, Iterator 對象可以被 next()函數調用並不斷返回下一個數據,直到沒有數據時拋出StopIteration 錯誤。可以把這個數據流看做是一個有序序列
,但我們卻不能提前知道序列的長度
,只能不斷通過 next()函數實現按需計算下一個數據,所以 Iterator 的計算是惰性的
,只有在需要返回下一個數據時它纔會計算。
Iterator 甚至可以表示一個無限大的數據流,例如全體自然數。而使用list 是永遠不可能存儲全體自然數的。
把Iterable對象變成 Iterator:
from collections import Iterator
print(isinstance(iter([]),Iterator)) #True
print(isinstance(iter('ABC'),Iterator)) #True
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
使用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