无码av一区二区三区无码,在线观看老湿视频福利,日韩经典三级片,成 人色 网 站 欧美大片在线观看

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

【python小技巧4】for循環(huán)原理與迭代器的實現(xiàn)

2023-01-03 23:02 作者:小倪同學(xué)0v0  | 我要投稿

對于新手,for 循環(huán)無非 for i in range(10):? for i in lst: 等,那你知道 for 循環(huán)真正的原理嗎?

目錄

  1. 你需要知道的...

  2. for 循環(huán)的工作原理(2種情況)

  3. 如何寫一個可迭代對象和迭代器

你需要知道的...

  1. for 循環(huán)的語法永遠(yuǎn)是?for?xxx?in?xxx,for 循環(huán)又稱遍歷循環(huán),本質(zhì)上一切?for 循環(huán),都是在遍歷一個對象,無論是 range 還是 list。

  2. 內(nèi)置函數(shù) 與 類的魔術(shù)方法?的關(guān)系

    python 里有很多“魔術(shù)方法”,它們都有一個共同點:以雙下劃線開頭,以雙下劃線結(jié)尾,如 __str__,__int__,__iter__,__next__ 等。(這也是為什么不推薦新手用 __xxx__ 這種當(dāng)變量名的原因)

    其中有很多魔術(shù)方法可被對應(yīng)的內(nèi)置函數(shù)調(diào)用,如 str(), int(),?iter(),?next() 等。

  3. 本文還涉及了一個魔術(shù)方法 __getitem__

    obj.__getitem__(item)? <==>? obj[item],就是列表的取元素操作

  4. 可迭代對象迭代器

    1. 可迭代對象指實現(xiàn)?__iter__ 方法,一般保存了數(shù)據(jù),如 list 等。

    2. 迭代器指實現(xiàn)了 __next__ 方法,一般保存了迭代的狀態(tài)(如迭代到哪一個),如 list_iterator 等。

    3. 嚴(yán)格定義如上,但有一條規(guī)定:迭代器應(yīng)該也是可迭代的。換句話說:如果一個對象實現(xiàn)了 __next__ 方法,那它也應(yīng)該實現(xiàn) __iter__ 方法,大部分就是返回自己。

      可迭代對象?與?迭代器的概念一定要記住,很重要!??!

    4. 如何檢測一個對象是否是迭代器或可迭代?使用內(nèi)置模塊?collections(新版建議用collections.abc 模塊)?下的?Iterable 和 Iterator 就可以,具體用法:

????????注意:字符串、列表、元組、字典、集合等是可迭代的,但不是迭代器!

假設(shè)有一個循環(huán):

以下將在這個循環(huán)的基礎(chǔ)上講解

第一種情況:

如果 obj 是可迭代的,即實現(xiàn)了 __iter__ 方法,嘗試調(diào)用 iter(obj) 得到 obj 的迭代器,假設(shè)迭代器是 iterator。

然后不斷調(diào)用 next(iterator),返回值就是迭代出來的值,直到遇到?StopIteration,停止循環(huán)。

這種情況下上面的代碼與下面是等價的:

第二種情況:

如果 obj 沒有實現(xiàn) __iter__ 方法,則康康有沒有實現(xiàn) __getitem__ 方法。

如果有,則從 0 開始,依次遞增 1 來調(diào)用 __getitem__ 方法,返回值就是迭代出來的值,直到遇到?StopIteration,停止調(diào)用。

這種情況下上面的代碼與下面是等價的:

如果以上兩種方法都行不通,那就不能用 for 循環(huán)(會報TypeError: 'xxx' object is not iterable)

下面再來講一講如何實現(xiàn)可迭代對象和迭代器

實現(xiàn)可迭代對象和迭代器

我們試著模仿 range 函數(shù)寫一個生成等差數(shù)列的可迭代對象

現(xiàn)在它既不是迭代器,也不可迭代

我們試著讓它的迭代器就是它自己(實現(xiàn) __iter__ 方法):

已經(jīng)可迭代了,接下來讓它成為迭代器

我們可以對它用 for 循環(huán)了:

但是,這種寫法有問題,慢慢看來:

我們要輸出一個 [1, 2, 3, 4, 5] 與它自己的笛卡爾積(不知道啥是笛卡爾積的看這里https://baike.baidu.com/item/%E7%AC%9B%E5%8D%A1%E5%B0%94%E4%B9%98%E7%A7%AF/6323173),即

傳統(tǒng)寫法是

這很簡單。但如果用咱們編的這個 Range,問題就出來了,看輸出:

問題就出在:因為有 return self 的存在,兩個 for 循環(huán)共用了一個迭代器(換而言之,這個 Range 對象只能用一次)!讓這個?Range 對象既保存數(shù)據(jù)又保存狀態(tài)是不行噠!

range 對象的 iter() 原理圖
自定義的 Range 對象的 iter() 原理圖

所以我們需要這里給出兩種解決方案:

(一)自定義專門的迭代器

最本質(zhì)的問題就是 __iter__ 方法里的 return self,我們再定義一個迭代器:

為了要滿足第三條規(guī)則,即迭代器應(yīng)該也是可迭代的,上面也說了,大部分就是返回自己,所以再給 RangeIterator 加上 __iter__ 方法:

這樣,Range 對象就可以多次使用了,但?RangeIterator 作為迭代器本來就只能使用一次。

至此,一個迭代器已經(jīng)實現(xiàn)了。

(二)使用生成器

我們下一章詳細(xì)討論生成器,這里不理解沒關(guān)系(挖坑*1)

我們將 __iter__ 方法變成一個生成器函數(shù):

也能達(dá)到效果,且更加簡潔,推薦使用這種方法。

至于我們剛才討論的第二種情況,實際使用中很少使用,我們就不再贅述。

END

這算是給之前的一章填坑了...

參考資料:

https://docs.python.org/3.8/tutorial/classes.html

https://docs.python.org/3.8/library/stdtypes.html

https://baike.baidu.com/item/%E7%AC%9B%E5%8D%A1%E5%B0%94%E4%B9%98%E7%A7%AF/6323173

以上內(nèi)容如有錯誤,歡迎指出!


【python小技巧4】for循環(huán)原理與迭代器的實現(xiàn)的評論 (共 條)

分享到微博請遵守國家法律
天长市| 花莲市| 会东县| 潢川县| 乌拉特后旗| 松阳县| 龙江县| 巴中市| 阜城县| 苏尼特左旗| 西乌珠穆沁旗| 平顺县| 呼图壁县| 邵阳县| 武陟县| 荣成市| 苗栗市| 辽宁省| 灵寿县| 孝义市| 丽水市| 德令哈市| 五台县| 甘孜县| 远安县| 呈贡县| 绵竹市| 鄂托克前旗| 福海县| 阿拉善右旗| 永胜县| 炉霍县| 台江县| 大悟县| 阜康市| 林周县| 龙井市| 南充市| 南阳市| 扬州市| 理塘县|