python3迭代器和可迭代对象_一文读懂 Python3 可迭代对象、迭代器、生成器区别...
筆者學(xué)習(xí)Python已有一段時間,一直以為對于可迭代對象(iterable)、迭代器(iterator)、生成器(generator)有一定理解了,直到看到《流暢的python》中的講解才有了更深的體會,話不多說,開始:
對于可迭代對象和迭代器常規(guī)的理解:若對象中實現(xiàn)了 __getitem__ 或者 __iter__ 方法,那么這個對象就是可迭代對象
2. 若對象中實現(xiàn)了 __next__ 和 __iter__ 方法,那么這個對象就是迭代器
3. 可迭代對象的背后其實是迭代器在起作用 (后面會說到)
那么什么是可迭代對象,事實上,python中的所有序列集合都是可迭代對象,并且他們都支持for循環(huán)遍歷。
>>> s = range(4)
>>> for i in s:
print(i)
0
1
2
3
>>> b = list(range(5))
>>> for i in b:
print(b)
0
1
2
3
4
>>> c = {'A':'a', 'B':'b', 'C':'c'}
>>> for key in c:
print(key)
A
B
C
>>> d = set([1,2,3,4])
>>> for i in d:
print(i)
1
2
3
4
為什么他們能夠使用for循環(huán)遍歷元素,背后就是迭代器在起作用,在執(zhí)行for循環(huán)時,可迭代對象通過iter()生成迭代器,然后遍歷迭代器中的元素。如果上述代碼不使用for想要達到相同的效果可以這樣做(用列表舉例說明):
>>> a
[0, 1, 2, 3, 4]
>>> iter_a = iter(a)
>>> while 1:
try:
print(next(iter_a))
except StopIteration: # 獲取異常
del iter_a
break
0
1
2
3
4
del 作用是廢棄當(dāng)前迭代器對象,因為迭代器對象遍歷一次就無法再遍歷了,原因是迭代器對象中的__next__方法,當(dāng)通過next(a)方法(此處a為迭代器對象)依次獲取到a中的所有元素,直到輸出StopIteration異常。由于上述在for語句中已經(jīng)對異常進行了處理,所以我們并不會看到,其實每次執(zhí)行for語句遍歷可迭代對象時都生成了一個迭代器,遍歷完后就廢棄掉。
其次就是在可迭代對象中的__iter__ 方法是實現(xiàn)了一個迭代器。看下面實現(xiàn)了一個數(shù)組對象:
#coding:utf-8
class Array():
def __init__(self, maxsize=20): # 指定數(shù)組的長度,默認為20
self.maxsize = maxsize
self._items = [None] * maxsize
def __len__(self): # 查看數(shù)組長度
return len(self._items)
def __getitem__(self, index):
if index >= self.maxsize: # 索引從0開始
raise Exception('out of the index')
return self._items[index]
def __setitem__(self, index, item):
if index >= self.maxsize: # 索引從0開始
raise Exception('out of the index')
self._items[index] = item
def clear(self):
for i,value in enumerate(self._items):
self._items[i] = None
def __iter__(self):
for item in self._items:
yield item
def append(self,item): # 尾部添加
self._items += [item]
在數(shù)組對象中實現(xiàn)了__iter__方法,在此方法中利用yield實現(xiàn)了生成器(生成器和迭代器在一般情況下,沒有區(qū)別。可以說所有生成器對象都是迭代器對象,有一點細微的區(qū)別:生成器對象更傾向于在無限中集合中惰性的輸出需要的數(shù)據(jù),而迭代器更傾向于在實現(xiàn)已知道所有數(shù)據(jù)的情況下惰性輸出需要的數(shù)據(jù),恰當(dāng)?shù)睦泳褪庆巢瞧鯏?shù)列,可以用生成器實現(xiàn)一個斐波那契數(shù)列,但因為該數(shù)列的元素是無限多個,所以說其是迭代器實現(xiàn)的就沒有說由生成器實現(xiàn)的說法恰當(dāng))
而在迭代器中也實現(xiàn)了__iter__方法,不過在迭代器中的__iter__方法是實現(xiàn)了如下的內(nèi)容:
def __iter__(self):
return self
在迭代器對象中的__iter__方法,返回了迭代器本身。這樣做的原因是,在需要可迭代對象的地方能夠使用迭代器。這個話可能有點繞,不過你想:對于可迭代對象,利用for循環(huán)其實利用__iter__方法生成了迭代器;那么如果對于迭代器,利用for循環(huán)呢,那么不也是利用__iter__方法生成迭代器嗎?但是這里不用生成,因為它本身就是迭代器,所以在迭代器對象中的__iter__方法實現(xiàn)了返回了迭代器本身。
判斷一個對象是否是迭代器,可以利用collections庫中的abc,它封裝了API,比如:
>>> from collections import abc
>>> s = range(9)
>>> isinstance(s, abc.Iterator)
False
>>> f = iter(list(s))
>>> isinstance(f, abc.Iterator)
True
如上,當(dāng)然你也可以使用next()方法直接看能否輸出對象中的元素。不過利用上述的方法能夠在程序中合理的區(qū)分迭代器和可迭代對象哦。
總結(jié)
以上是生活随笔為你收集整理的python3迭代器和可迭代对象_一文读懂 Python3 可迭代对象、迭代器、生成器区别...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 没有信用卡怎么贷款
- 下一篇: python mro c3_python