日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python3迭代器和可迭代对象_一文读懂 Python3 可迭代对象、迭代器、生成器区别...

發(fā)布時間:2024/9/19 python 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python3迭代器和可迭代对象_一文读懂 Python3 可迭代对象、迭代器、生成器区别... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

筆者學(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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。