成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Python中可迭代對(duì)象、迭代器是什么-創(chuàng)新互聯(lián)

創(chuàng)新互聯(lián)www.cdcxhl.cn八線動(dòng)態(tài)BGP香港云服務(wù)器提供商,新人活動(dòng)買(mǎi)多久送多久,劃算不套路!

讓客戶(hù)滿(mǎn)意是我們工作的目標(biāo),不斷超越客戶(hù)的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛(ài)。我們立志把好的技術(shù)通過(guò)有效、簡(jiǎn)單的方式提供給客戶(hù),將通過(guò)不懈努力成為客戶(hù)在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:主機(jī)域名、虛擬主機(jī)、營(yíng)銷(xiāo)軟件、網(wǎng)站建設(shè)、皮山網(wǎng)站維護(hù)、網(wǎng)站推廣。

小編給大家分享一下Python中可迭代對(duì)象、迭代器是什么,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!

在Python中,有這兩個(gè)概念容易讓人混淆。第一個(gè)是可迭代對(duì)象(Iterable),第二個(gè)是迭代器(Iterator),第三個(gè)是生成器(Generator),這里暫且不談生成器。

可迭代對(duì)象

列表、元組、字符串、字典等都是可迭代對(duì)象,可以使用for循環(huán)遍歷出所有元素的都可以稱(chēng)為可迭代對(duì)象(Iterable)。在Python的內(nèi)置數(shù)據(jù)結(jié)構(gòu)中定義了Iterable這個(gè)類(lèi),在collections.abc模塊中,我們可以用這個(gè)來(lái)檢測(cè)是否為可迭代對(duì)象。

>>> from collections import Iterable
>>> a = [1,2,3]
>>> isinstance(a, Iterable)
>>> True
>>> b = 'abcd'
>>> isinstance(b, Iterable)
>>> True

這些數(shù)據(jù)結(jié)構(gòu)之所以能稱(chēng)之為Iterable,是因?yàn)槠鋬?nèi)部實(shí)現(xiàn)了__iter__()方法,從而可迭代。當(dāng)我們使用for循環(huán)時(shí),解釋器會(huì)調(diào)用內(nèi)置的iter()函數(shù),調(diào)用前首先會(huì)檢查對(duì)象是否實(shí)現(xiàn)了__iter__()方法,如果有就調(diào)用它獲取一個(gè)迭代器(接下來(lái)會(huì)講)。加入沒(méi)有__iter__()方法,但是實(shí)現(xiàn)了__getitem__()方法,解釋器會(huì)創(chuàng)建一個(gè)迭代器并且按順序獲取元素。如果這兩個(gè)方法都沒(méi)有找到,就會(huì)拋出TypeError異常。下面我們自定義對(duì)象,分別實(shí)現(xiàn)這兩個(gè)方法(getitem(), iter())

class MyObj:
    def __init__(self, iterable):
        self._iterable = list(iterable)
    def __getitem__(self, item):
        return self._iterable[item]
obj = MyObj([1,2,3])
for i in obj:
    print(i)

如上所示,這里沒(méi)有實(shí)現(xiàn)__iter__方法,只實(shí)現(xiàn)了__getitem__方法,也使得Myobj稱(chēng)為可迭代對(duì)象。

下面我們實(shí)現(xiàn)__iter__方法,這里使用了yield語(yǔ)法用來(lái)產(chǎn)出值(這里需要生成器的知識(shí))

class MyObj:
    def __init__(self, iterable):
        self._iterable = list(iterable)
    def __iter__(self):
        index = 0
        while True:
            try:
                yield self._iterable[index]
            except IndexError:
                break
            index += 1
obj = MyObj([1,2,3])
for i in obj:
    print(i)

這里同樣讓對(duì)象稱(chēng)為可迭代對(duì)象。

迭代器

迭代器是一個(gè)可以記住遍歷的位置的對(duì)象。

迭代器對(duì)象從集合的第一個(gè)元素開(kāi)始訪問(wèn),直到所有的元素被訪問(wèn)完結(jié)束。迭代器只能往前不會(huì)后退。

Python中可迭代對(duì)象、迭代器是什么

如上圖所示,迭代器(Iterator)繼承可迭代(Iterable),迭代器必須實(shí)現(xiàn)__iter__方法和__next__方法。其中__next__方法用于產(chǎn)出下一個(gè)元素。

由繼承圖可見(jiàn),迭代器一定是可迭代對(duì)象,可迭代對(duì)象不一定是迭代器。

迭代器有兩個(gè)基本的方法:iter() 和 next()。

我們使用iter(iterable)即可把可迭代對(duì)象轉(zhuǎn)換成迭代器。

使用next(iterator)來(lái)獲取迭代器的下一個(gè)值。

>>> a = [3,4,5]
>>> a
>>> [3, 4, 5]
>>> iter(a)
>>> <list_iterator object at 0x10b130ba8>
>>> iterator = iter(a)
>>> next(iterator)
>>> 3
>>> next(iterator)
>>> 4
>>> next(iterator)
>>> 5
>>> next(iterator)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
StopIteration

如上所示,因?yàn)閷?duì)象實(shí)現(xiàn)了__next__方法,我們可以通過(guò)next(iterator)來(lái)獲取迭代器的下一個(gè)值,直到?jīng)]有值了,拋出StopIteration異常結(jié)束。

迭代器的背后

迭代器Iterator是一個(gè)抽象基類(lèi),它定義在_collections_abc.py中

Iterator源碼如下

class Iterator(Iterable):
    __slots__ = ()
    @abstractmethod
    def __next__(self):
        'Return the next item from the iterator. When exhausted, raise StopIteration'
        raise StopIteration
    def __iter__(self):
        return self
    @classmethod
    def __subclasshook__(cls, C):
        if cls is Iterator:
            return _check_methods(C, '__iter__', '__next__')
        return NotImplemented

可以看到,它實(shí)現(xiàn)了__subclasshook__方法,即不用顯式繼承Iterator,只需要實(shí)現(xiàn)__iter__和__next__方法即可稱(chēng)為Iterator的虛擬子類(lèi)。這里凸現(xiàn)了Python的鴨子類(lèi)型,實(shí)現(xiàn)特定的“協(xié)議”即可擁有某種行為。

另外,它自己也定義了__iter__方法,當(dāng)我們使用iter(Iterator)時(shí)直接返回自己,不做任何處理。

iter()函數(shù)的兩個(gè)用法

官方文檔中給出了說(shuō)明:

    iter(iterable) -> iterator
    iter(callable, sentinel) -> iterator
    
    Get an iterator from an object.  In the first form, the argument must
    supply its own iterator, or be a sequence.
    In the second form, the callable is called until it returns the sentinel.

第一個(gè)用法:iter(iterable) -> iterator (把可迭代對(duì)象轉(zhuǎn)換為迭代器)

第二個(gè)用法:iter(callable, sentinel) -> iterator (第一個(gè)參數(shù):任何可調(diào)用對(duì)象,可以是函數(shù),第二個(gè)是標(biāo)記值,當(dāng)可調(diào)用對(duì)象返回這個(gè)值時(shí),迭代器拋出StopIteration異常,而不產(chǎn)出標(biāo)記值)

>>> from random import choice
>>> values = [1,2,3,4,5,6,7]
>>> def test_iter():
>>>     return choice(values)
>>> it = iter(test_iter, 2)
>>> it
>>> <callable_iterator object at 0x10b130b00>
>>> for i in it:
>>>     print(i)
>>> 7
>>> 1
>>> 7
>>> 3
>>> 1

上面代碼的流程:test_iter函數(shù)從values列表中隨機(jī)挑選一個(gè)值并返回,調(diào)用iter(callable, sentinel)函數(shù),把sentinel標(biāo)記值設(shè)置為2,返回一個(gè)callable_iterator實(shí)例,遍歷這個(gè)特殊的迭代器,如果函數(shù)返回標(biāo)記值2,直接拋出異常退出程序。這就是iter函數(shù)的鮮為人知的另一個(gè)用法。

看完了這篇文章,相信你對(duì)Python中可迭代對(duì)象、迭代器是什么有了一定的了解,想了解更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道,感謝各位的閱讀!

分享標(biāo)題:Python中可迭代對(duì)象、迭代器是什么-創(chuàng)新互聯(lián)
鏈接URL:http://jinyejixie.com/article28/ddsjjp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器、靜態(tài)網(wǎng)站、微信公眾號(hào)、手機(jī)網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站建設(shè)、微信小程序

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

營(yíng)銷(xiāo)型網(wǎng)站建設(shè)
蚌埠市| 三穗县| 濉溪县| 资源县| 尼木县| 会同县| 长葛市| 上虞市| 云浮市| 吴堡县| 柏乡县| 海原县| 奎屯市| 象山县| 垣曲县| 和顺县| 固原市| 金堂县| 新田县| 盖州市| 广元市| 鸡西市| 博白县| 榆社县| 萨嘎县| 馆陶县| 小金县| 噶尔县| 松溪县| 韶关市| 文安县| 灯塔市| 宜黄县| 临湘市| 定边县| 清镇市| 开江县| 岑溪市| 武汉市| 哈尔滨市| 闽清县|