1. 程式人生 > >叠代器超詳細攻略

叠代器超詳細攻略

來看 versions pytho with macbookp projects log ons 有效

寫的很墨跡,將就看。

首先 理解 for 循環

for i in [1,2,3,4]

print i

這個是正常

如果 for 循環一個 1234

會報錯,因為 int 不是一個 iterable 類型

iterable : 字典裏的意思是 可叠代的, 可重復的

可叠代的對象: 字符串str 列表 list 元組 tuple 字典 dict 集合set

#證明是否可叠代
from collections import Iterable

l = [12,3,4]
t = (1,2,3,4)
d = {1:2,3:4}
s = {1,2,3,4}

print(isinstance(l,Iterable))
print(isinstance(t,Iterable))
print(isinstance(d,Iterable))
print(isinstance(s,Iterable))


# 清一色的 True

結合 for 循環取值的現象,再從字面上理解一下
叠代其實就是 : 可以將某個數據 一個接著一個取出來



那麽可叠代協議這麽理解呢?

首先,能被 for 循環的就是‘可叠代的’可以被叠代滿足的要求就叫做叠代器協議。
可叠代協議的定義: 內部實現了__iter__方法。

綜上總結!!! 可以被 for 循環的都是可叠代的,要想可叠代,內部必須有一個__iter__方法。



那麽這個__iter__做了些什麽事?

print([2,3,4].__iter__())

輸出結果:<list_iterator object at 0x1005d94a8>

Iterable 可叠代
iterator 叠代器

叠代器是個什麽鬼東西, 一會一個可叠代,一會一個叠代器,我英語一直都不好, 我也沒打算再補。。。

為了python 我忍了


好 那麽,我們來看一看這個帶 iter 的列表和普通列表在功能實現上面有什麽不一樣 好不好

‘‘‘‘
l([1,2].__iter__())是列表叠代器中實現的所有方法,l[1,2]是列表中實現的所有方法,
都是以列表的形式返回給我們,為了看的更清楚,我們分別把他們轉換成集合。 然後取差集
‘‘‘
#
# print(dir([1,2].__iter__()))
# print(dir([1,2]))

print(set(dir([1,2].__iter__())) - set(dir(dir([1,2]))))
#註意盯著看你的括號是否給到位

輸出結果:

/Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6 "/Users/macbookpro/PycharmProjects/叠代器生成器/blog 代碼.py"
{‘__length_hint__‘, ‘__next__‘, ‘__setstate__‘}

Process finished with exit code 0

重點就看 最後多出來的那三個方法

{‘__length_hint__‘, ‘__next__‘, ‘__setstate__‘}

那麽我們繼續來看這三個方法,分別都是幹啥的,什麽來路!

iter_l = [1,2,3,4,5,6].__iter__()
#獲取叠代器中元素的長度 print(iter_l.__length_hint__())
#根據索引值指定從哪裏開始叠代 print(‘*‘,iter_l.__setstate__(4))
!!!!!!#一個一個的取值 print(‘**‘,iter_l.__next__()) print(‘***‘,iter_l.__next__())



好的,這三個辦法我們都一個個試過了。
來, 跟著我回歸一下初心 捫心問問自己,今天我們學的是啥。
對,最上面寫的有,但是我怕我忘,在這再回憶一下。
能用 for 循環的的都是可叠代的,可叠代的內部都使用了__iter__方法

__iter__是根據可叠代協議定出來的,沒有為什麽 你就這樣記就行

然後響指!各位寶貝, 上述三個方法中,能一個一個取值,感覺和 for 循環一樣樣的是誰?
對!沒錯!是他!我們的朋友,小哪咤= __next__

再 for 循環中,就是在內部調用了__next__方法,才能一個一個取值

‘‘‘
我是很純很純並且很蠢and 年齡還大的小白一個,啥也不會,腦子也笨,剛看過的句子 ,到句號 我就忘記句號前面的東西了。
代碼沒思路 也理解不了, 我要是真的會,我幹嘛要一遍一遍的翻博客,早進行下面的東西了,
但是這個東西,你學會了 別人也拿不走,以後說不定 你多會一句, 你就能比別人多裝一個很完美
逼格很高的比了
目前我的辦法是, 只要有時間, 理解代碼理解思路
剛開始看到這麽一堆我20多年沒見過沒接觸的11002200312030還有這個那個 的時候
我是懵逼 並且很不把它當做一回事的,
可是 真的 被這個破 python 教育的不要不要的, 沒有什麽不勞而獲,就算有那個人也不是你
深深深深深深*******n 的挫敗感 越是讓我不好受,我越要征服你。
各位一起加油!!!
‘‘‘


來,接著上面,我們碼起來, 你看再多,不如自己照著碼一遍有用,碼一遍你沒收獲,那就再碼繼續碼


#用叠代器的 next 方法來寫一個不依賴 for 的遍歷
l = [1,2,3,4]
‘‘‘
__iter__是上面說過的,
想要可叠代內部必須有__iter__方法
這裏就是先調用這個方法,讓這個列表可叠代
然後下面就是用__next__取值
‘‘‘
l_iter = l.__iter__()
item = l_iter.__next__()
print(item)

item = l_iter.__next__()
print(item)

item = l_iter.__next__()
print(item)

item = l_iter.__next__()
print(item)

item = l_iter.__next__()
print(item)

item = l_iter.__next__()
print(item)

打印結果:

StopIteration
1
2
3
4

報錯了,但是這個報錯我們不尷尬,因為我們把叠代器裏的元素取完了,然後你還要取它就給

你拋出一個異常StopIterration,就是在告訴我們,列表中已經沒有有效的元素了。

如何處理呢?
comeon
l = [1,2,3,4]
#先把它轉化為可叠代的用 iter
l_iter = l.__iter__()
while 1 :
try:
#取它值 用 next
item = l_iter.__next__()
print(item)
except StopIteration:
break


好, 那麽everybody ,我們是如何用 while 循環來實現 for 循環的功能呢,
來看 我們是從誰哪裏拿的一個又一個的值啊, 是媽媽??!
l_iter 就是一個叠代器
so 總結一下: 叠代器遵循叠代器協議:必須擁有__iter__和__next__方法。

來吧, 看一下 range()是個什麽鬼。我們目前可以確定的是, 它肯定是一個可叠代對象,來查一波
看看他是不是一個叠代器

print(‘__next__‘in dir(range(7)))
print(‘__iter__‘in dir(range(7)))

from collections import Iterator
print(isinstance(range(100),Iterator))


打印結果: False True False

so想要可叠代 內部必須有__iter__方法和__next__方法 so range()不是一個叠代器




是,很多東西我們也可以通過下標來取值, 比如序列類型字符串,列表,元組
但是,那些沒有下標的呢,它們不要面子的嗎? 你覺得字典,集合這些非序列類型不夠漂亮嗎?
so for 循環就是基於叠代器協議提供了一個統一的可以遍歷所有對象的方法,就是我們上面說的
調用對象的__iter__方法將其轉換成一個叠代器,然後使用叠代器協議取實現循環訪問,這樣
所有的對象就都可以通過 for 循環來遍歷了。



下一篇是生成器。

































叠代器超詳細攻略