在使用for語句的時候,相當於python內部把for后面的對象使用了iter()方法。
a = [1, 2, 3]
for i in a:
do_something()
for i in iter(a):
do_something()
iter()的返回是一個迭代對象,主要映射到了類里的__iter__()方法。
對於使用iter()方法的對象,返回值為對象中的__iter__()方法的返回值。
iter()方法返回的是一個實現了__next__()方法的對象,由該對象實現的__next__()方法來完成實際的迭代。
class Node:
def __iter__(self):
return iter([1, 2, 3])
if __name__ == "main":
n = Node()
for i in n:
print(i)
結果為:
1
2
3
Iterable:有迭代能力的對象,一個類,實現了__iter__(),就認為有迭代能力,通常此函數必須返回一個實現了__next__()的對象,如果自己實現了,可以返回self(返回值不是必須的)。
Iterator:迭代器,同時實現了__iter__()和__next__()的對象。(若某個自定義類只實現了__next__()而未實現__iter__()則會報錯)
在調用iter()方法的時候(例如for循環時),生成了一個迭代對象,要求__iter__()返回一個實現了__next__()的對象,可通過next()方法訪問這個對象的下一個元素。如果不添加StopIteration異常,會不斷迭代,for循環會捕捉這個異常並停止迭代。
class MyIter:
def __init__(self):
self._start = 0
def __iter__(self):
return self
def __next__(self):
if self._start < 10:
self._start += 1
return self._start
else:
raise StopIteration
if __name__ == '__main__':
a = MyIter()
for i in a:
print(i)
結果:
1
2
3
4
5
6
7
8
9
10
如果同時實現了__iter__()和__next__()方法,且__iter__()沒有返回self,調用iter方法時會返回__iter__()返回的結果
class MyIter:
def __init__(self):
self._start = 0
def __iter__(self):
return iter([1, 2, 3])
def __next__(self):
if self._start < 10:
self._start += 1
return self._start
else:
raise StopIteration
if __name__ == '__main__':
a = MyIter()
for i in a:
print(i)
結果:
1
2
3
調用iter()方法時,iter()僅會被調用一次,next()則會多調用多次。
具體體現:
class MyIter:
def __init__(self):
self._start = 0
def __iter__(self):
self._start += 8
return self
def __next__(self):
if self._start < 10:
self._start += 1
return self._start
else:
raise StopIteration
if __name__ == '__main__':
a = MyIter()
for i in a:
print(i)
結果:
9
10
迭代器的優點:
- 如果采用列表的方式遍歷,會將列表中所有內容載入內存;如果使用迭代器,只有調用了next()方法時才會返回對應的結果,可以節約內存。
- 不依賴索引的讀取方式。
迭代器的缺點: - 只能往后取值,不能往前取值;不能指定某一個值。
- 無法預測迭代器的長度。
不能指定某一個值體現於:
a = iter([1, 2, 3])
print(a[1])
Traceback (most recent call last):
File "D:/Project/python_fundamental/iterator_try/main.py", line 23, in <module>
print(a[1])
TypeError: 'list_iterator' object is not subscriptable