容器是用來儲存元素的一種資料結構,容器將所有資料儲存在記憶體中,python中典型的容器有:list,set,dict,str
等等。
class
test()
:def
__init__
(self,data=1)
: self.data = data
def__iter__
(self)
:return self
def__next__
(self)
:if self.data >5:
raise stopiteration
else
: self.data+=
1return self.data
for item in test(3)
:print
(item)
for … in…
這個語句其實做了兩件事。第一件事是獲得乙個可迭代器,即呼叫了__iter__()
函式。
第二件事是迴圈的過程,迴圈呼叫__next__()
函式。
對於test
這個類來說,它定義了__iter__
和__next__
函式,所以是乙個可迭代的類,也可以說是乙個可迭代的物件(python中一切皆物件)。
含有__next__()
函式的物件都是乙個迭代器,所以test
也可以說是乙個迭代器。如果去掉__itet__()
函式,test
這個類也不會報錯。如下**所示:
class
test()
:def
__init__
(self,data=1)
: self.data = data
def__next__
(self)
:if self.data >5:
raise stopiteration
else
: self.data+=
1return self.data
t = test(3)
for i in
range(3
):print
(t.__next__(
))
生成器是一種特殊的迭代器。當呼叫fib()
函式時,生成器例項化並返回,這時並不會執行任何**,生成器處於空閒狀態,注意這裡prev, curr = 0, 1
並未執行。然後這個生成器被包含在list()
中,list
會根據傳進來的引數生成乙個列表,所以它對fib()
物件(一切皆物件,函式也是物件)呼叫__next()__
方法,
def
fib(end =
1000):
prev,curr=0,
1while curr < end:
yield curr
prev,curr=curr,curr+prev
print
(list
(fib())
)
[1,
1,2,
3,5,
8,13,
21,34,
55,89,
144,
233,
377,
610,
987]
在使用列表時,直接將資料存入列表將會佔據大量空間,且復用率較低,為解決這個問題,這裡了解一下迭代器,從而建立一種資料產生的方式,以此來節省空間。
注意,這裡需要使用到內建函式__iter__
,簡單理解為,使用了__iter__
才會是乙個可迭代物件,關於這部分,我們可以對一些物件做一些判斷,從而清楚是不是可迭代物件,比如l1
列表:
from collections.abc import iterable
# 判斷l1是否為可迭代物件
l1 =
[i for i in
range(4
)]print
(isinstance
(l1, iterable)
)# 結果為true,確定為迭代物件
這裡我們使用__iter__()
方法和__next__()
方法來將元素取出。
l2 = l1.__iter__(
)# l2 = iter(l1) # 和上面一句等價
print
(next
(l2)
)print
(l2.__next__())
# 和上面一句等價
print
(next
(l2)
)
在這裡我們實現了使用for
迴圈來取出元素的方法,在了解這裡之後,我們開始做乙個自己的迭代器
# 構造迭代器
class
newiter()
:# 用於生成斐波那契數列
def__init__
(self, num)
: self.num = num
self.a =
0 self.b =
1def
__iter__
(self)
:# 建立可迭代物件
return self
def__next__
(self)
:while self.num >0:
result = self.a
self.a, self.b = self.b, self.a + self.b
self.num -=
1return result
# 迴圈結束後跳出
raise stopiteration
new_iter = newiter(5)
print
(next
(new_iter)
)print
(next
(new_iter)
)
這裡引入生成器個概念,生成器能做到迭代器能做的所有事,由於自動建立了iter()
和next()
方法,生成器顯得特別簡潔。除了建立和儲存程式狀態的自動方法,當發生器終結時,還會自動丟擲stopiteration
異常。簡單理解他就是迭代器的一種!!使用yield
即可實現。
# 生成器實現
defnew_create
(num)
:# 用於生成斐波那契數列
a, b =0,
1while num >0:
yield a
a, b = b, a+b
num -=
1
new_iter = new_create(5)
print
(next
(new_iter)
)print
(next
(new_iter)
)
目的就是節省空間,提高復用率 python的iter 與next 函式
list tuple等都是可迭代物件,我們可以通過iter 函式獲取這些可迭代物件的迭代器。然後我們可以對獲取到的迭代器不斷使 next 函式來獲取下 條資料。iter 函式實際上就是調 了可迭代物件的iter 法。li 11 22,33 44,55 li iter iter li next li ...
python 內建函式 iter
本文主要想說明 如果iter 函式的引數是乙個容器物件,那麼iter 函式返回該容器物件的乙個新的迭代器。如果iter 函式的引數是乙個迭代器,那麼iter 函式返回輸入的迭代器。可以根據這個性質,連續執行兩次iter 判斷輸入iter 的是容器物件還是迭代器。直接上 usr bin env pyt...
python 深入分析iter函式
在python中迭代物件x時會呼叫iter x 可是,iter函式還有乙個鮮為人知的用法 傳入兩個引數,使用常規的函式或任何可呼叫的物件建立迭代器。這樣使用時,第乙個引數必須是可呼叫的物件,用於不斷呼叫 沒有引數 產出各個值 第二個值是哨符,這是個標記值,當可呼叫的物件返回這個值時,觸發迭代器丟擲s...