1. 程式人生 > 其它 >python迭代器簡單理解 __iter__和__next__方法

python迭代器簡單理解 __iter__和__next__方法

在使用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