學習python有一段時間了,在學習過程中遇到很多難理解的東西,做一下總結,希望能對其他朋友有一些幫助。
完全是個人理解,難免有錯,歡迎其他大神朋友們批評指正。
1 迭代
什麼是迭代呢??我們可以這樣理解,乙個容器型別的資料,比如 列表[ ] 、元組 () 和 字典 , 我們可以把這樣型別的資料放入for temp in [1,2,3] 當中,temp 被一次一次的賦值成為後面容器內資料,然後我們拿到temp進行一些想做的事情。那麼for 迴圈中自動的幫我們把資料一次一次的取出來,可以理解成,這樣的操作就是迭代。
2 可迭代物件
在python當中有有那麼一些特定的資料型別,可以放入for in 迴圈當中,這樣的資料型別,我們可以說他們是可迭代物件。
我們可以用 isinstance方法來檢測乙個物件是不是可迭代物件。
可迭代物件可以放入for in中迭代,也可以放入list() tuple()等幫我們快速生成乙個資料。
上**!
1from collections import
iterable23
( isinstance( , iterable ) ) #true
4print
( isinstance( {} , iterable ) ) #true
5print
( isinstance( () , iterable ) ) #true
6print( isinstance( 1 , iterable ) ) #false
從中我們可以看出來,列表、元組、字典都是可迭代物件。而整型資料不是可迭代物件。
可迭代物件的實質是怎麼回事呢???? (一臉懵逼)
其實,可迭代物件的內部必須實現乙個方法,__iter__()方法,這個方法的功能是,返回乙個迭代器,這個迭代器是幫助自己進行迭代的。實現這個方法的物件,python就認為它是可迭代物件。
迭代器又是啥???(二臉懵逼)不要著急 稍後我再分享
上**!!先看一看可迭代物件:
1from collections import
iterable2#
我們自己建立乙個類 裡面實現iter方法 python就認為它的物件是可迭代物件了
3class
myiterableobj(object):
4def
__iter__
(self):
5pass
67 demo1 =myiterableobj()
8print(isinstance( demo1 , iterable )) #
true
從中可以看出來,我們自己寫乙個類,裡面實現了iter方法,即使什麼都沒有做,建立乙個物件之後,判斷一下 python就認為這個物件是乙個可迭代物件了。
3 迭代器
剛剛我們說了,可迭代物件裡面的iter方法返回乙個幫助自己迭代的迭代器。迭代器是什麼呢??
其實我也不知道!(嘻嘻 笑哭) 開玩笑的啦~~~
在我的理解當中呢,迭代器是幫助可迭代物件乙個乙個把裡面元素取出來的乙個物件。迭代器型別的物件都是可迭代物件,為什麼呢,我們來看一看實質。
迭代器的實質:
迭代器內部必須實現兩個方法: __iter__() 和 __next__()
__iter__() 功能是返回乙個迭代器,幫助我們自己這種型別進行迭代,因為自己就是迭代器,所以迭代器中的__iter__() 返回的是self自己
__next__() 功能是: 簡單的說就是返回當前元素的,就像列表當中,取出第乙個元素,再呼叫next的時候就取出了第二個元素。 但是在for迴圈當中放入列表的時候,for是怎麼知道列表最後乙個元素都已經取完了呢????(我的天啊!不知道啊!!嗚嗚!!!)別著急,繼續往下看
複雜的說, next會做兩件事:1 如果當前資料沒有超出範圍,這次當前值返回,然後自己進行標記,找到下乙個要返回的值。
2 如果當前迭代器上次取出了最後乙個元素,這一次當前資料是在範圍之外的,那麼就丟擲異常(stopiteration),告訴for迴圈等一些內建工具,迭代結束了。
不是很理解??沒關係,上**我們來看看!!
我們先看一看 python中認為什麼樣的東西是迭代器:
from collections importiterator
print( isinstance( , iterator ) ) #
false 很顯然,可迭代物件不是迭代器
print( isinstance( .__iter__() , iterator ) ) #
true 這是呼叫了可迭代物件的iter方法得到乙個迭代器物件
#在python中 內建了 iter() 方法和 next() 方法,把物件傳進去與__iter__ 和 __next__ 相同功能
print( isinstance( iter() , iterator ) ) #
true
#像我說的 我們自己實現乙個迭代器
class
myiterator(object):
def__iter__
(self):
pass
def__next__
(self):
pass
demo2 =myiterator()
print( isinstance(demo2 , iterator ) ) #
true
看的出來,我們自己的類物件裡面只要具有這兩個方法 python就認為他是迭代器了。
大家還記不記得我說過,迭代器都是可迭代物件, 因為迭代器一定有__iter__方法,所以它一定是迭代物件
ok!接下來呢,我們把兩個函式的業務邏輯補全,看一看迭代器兩個方法實際上在幹什麼??
我們來實現乙個 傳入乙個n 給我們迭代出 0到n 的迭代器 這個功能就好像是 range(n) 一樣 我們自己實現一下!
1'''2
接下來,我們具體實現乙個能夠完成功能, 能夠放入for迴圈遍歷的迭代器!! 啊好刺激啊!!
3我們要實現的業務是: 傳入乙個引數n , 我們要迭代出 0到n的數
4'''
5class
numiterator(object):6#
初始化我們接收乙個引數n 告訴我們迭代到多少結束
7def
__init__
(self , n):
8 self.n =n9#
我們實際上是把 i 交給函式呼叫者
10 self.i =011#
iter方法 返回乙個迭代器,自己就是迭代器 所以返回自己
12def
__iter__
(self):
13return
self14#
next方法 判斷是否越界 如果不越界返回乙個元素 如果越界了丟擲異常
15def
__next__
(self):16#
如果 沒有越界, 我們返回給呼叫者迭代結果,並且自己記錄下一次迭代的位置
17if self.i <=self.n:
18 res =self.i
19 self.i += 1
20return
res21
#進入else說明i已經超過n 迭代越界了 丟擲異常告訴for迴圈 迭代結束了
22else:23
#如果不丟擲這個異常,for迴圈不知道什麼時候停止迭代 會不停的呼叫next 陷入死迴圈
24raise
stopiteration
2526
#乙個前3的自然數的迭代器物件
27 demo3 = numiterator(3)28#
之前說過, 我們可以呼叫python內建的next方法來獲取迭代器的元素
29print( next(demo3) ) #030
print( next(demo3) ) #131
print( next(demo3) ) #232
print( next(demo3) ) #333
#print( next(demo3) ) # 這時候再呼叫會丟擲異常 因為越界了!
3435
#同樣我們自己寫的迭代器能夠放入for迴圈當中
36 demo4 = numiterator(10)
37for num in
demo4 :
38print
(num)39#
我們發現,會列印出從0 到 10 然後for迴圈就停了
看完上面的**,我來解釋一下 其實for迴圈的實質:
for 不知道我們放在in後面的是可迭代物件還是迭代器,他會先呼叫iter方法拿到乙個迭代器,然後不停的呼叫next方法取到值,然後提供給我們,一直到取某個值的時候接收到了乙個stopiteration異常,for迴圈就終止了。
ok!! 到這裡呢,可迭代物件、迭代器的知識就跟大家分享完了。
不知道小夥伴們都有沒有理解,希望對一些不理解這些深層次東西的同學有一些幫助!!
我是稀里糊塗的林老冷~
Python高階專題 可迭代物件協議以及迭代器
1.迭代協議與可迭代物件 只有實現了迭代協議 iter 才可以稱為可迭代物件 2.迭代器 訪問集合內元素的方式,用於遍歷資料,但是無法返回,提供了惰性訪問資料,同時實現了 iter 以及 next 協議 from collections.abc import iterable,iterator it...
Python 可迭代物件
1.可迭代物件 以直接作用於for迴圈的資料型別有以下幾種 一類是集合資料型別 如 list tuple dict set str等 一類是generator,包括生成器和帶yield 的 generator function 這些可以直接作用於for迴圈的物件統稱為可迭代物件 iterable 2...
python可迭代物件
0 在python中只要是能用for in的,都是可迭代物件,讓我們看下定義 定義 我們已經知道可以對list tuple dict set str等型別的資料使用for in 的迴圈語法,會從其中依次拿到資料元素進行使用,我們把這樣的過程稱為遍歷,也叫迭代。所以我們把可以通過for in 這類語句...