在已知的可直接作用於for迴圈的數據類型有以下幾種 第一類 list tuple dict set str 第二類 generator 可直接作用於for迴圈的對象統稱為可迭代對象:Iterable 可利用 isinstance() 判斷一個對象是否是 Iterable 對象 from collec ...
在已知的可直接作用於for迴圈的數據類型有以下幾種
第一類
- list
- tuple
- dict
- set
- str
第二類
- generator
可直接作用於for迴圈的對象統稱為可迭代對象
:Iterable
可利用
isinstance()
判斷一個對象是否是
Iterable
對象
from collections.abc import Iterable
isinstance([], Iterable)
>>> True
isinstance({}, Iterable)
>>> True
isinstance('abc', Iterable)
>>> True
isinstance((x for x in range(10)), Iterable)
>>> True
isinstance(100, Iterable)
>>> False
可以被next()
函數調用並不斷返回下一個值的對象稱為迭代器
:Iterator
可利用
isinstance()
判斷一個對象是否是
Iterable
對象
from collections.abc import Iterator
isinstance((x for x in range(10)), Iterator)
>>> True
isinstance([], Iterator)
>>> False
isinstance({}, Iterator)
>>> False
isinstance(100, Iterator)
>>> False
生成器都是Iterator
對象,但list
、dict
、str
雖然是Iterable
,卻不是Iterator
。
把list
、dict
、str
等Iterable
變成Iterator
可以使用iter()
函數:
isinstance(iter([]), Iterator)
>>> True
isinstance(iter('abc'), Iterator)
>>> True
list
、dict
、str
為啥不是Iterator
?
原因:
因為
Python
的Iterator
對象表示的是一個數據流,Iterator
對象可以被next()
函數調用並不斷返回下一個數據,直到沒有數據時拋出StopIteration
錯誤。可以把這個數據流看做是一個有序序列,但我們卻不能提前知道序列的長度,只能不斷通過next()
函數實現按需計算下一個數據,所以Iterator
的計算是惰性的,只有在需要返回下一個數據時它才會計算。
Iterator
甚至可以表示一個無限大的數據流,例如全體自然數。而使用list是永遠不可能存儲全體自然數的。
小結
-
凡是可作用於for迴圈的對象都是Iterable類型;
-
凡是可作用於next()函數的對象都是Iterator類型,它們表示一個惰性計算的序列;
-
集合數據類型如list、dict、str等是Iterable但不是Iterator,不過可以通過iter()函數獲得一個Iterator對象。
-
可迭代對象和迭代器,通過函數tier()轉換
-
迭代器:數據流,變長,惰性的
Python的for迴圈本質上就是通過不斷調用next()函數實現的,例如:
for x in [1, 2, 3, 4, 5]:
pass
實際上完全等價於:
# 首先獲得Iterator對象:
it = iter([1, 2, 3, 4, 5])
# 迴圈:
while True:
try:
# 獲得下一個值:
x = next(it)
except StopIteration:
# 遇到StopIteration就退出迴圈
break