最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(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)的評論 (共 條)

分享到微博請遵守國家法律
增城市| 徐州市| 如皋市| 新巴尔虎右旗| 正定县| 睢宁县| 巩留县| 交口县| 融水| 绥江县| 涞水县| 禹城市| 西林县| 霍邱县| 嘉鱼县| 东兴市| 寿阳县| 新巴尔虎左旗| 昭苏县| 秀山| 乌拉特后旗| 新和县| 镇坪县| 通州区| 黄石市| 襄汾县| 策勒县| 图们市| 进贤县| 邮箱| 汝南县| 桓仁| 东源县| 沂水县| 东兰县| 即墨市| 三原县| 新邵县| 从江县| 桑植县| 昌黎县|