首頁  >  文章  >  後端開發  >  python迭代器與生成器的詳細介紹

python迭代器與生成器的詳細介紹

高洛峰
高洛峰原創
2017-03-22 10:00:101250瀏覽

一.什麼玩意是迭代器?

先說說什麼是迭代吧,迭代就是一件事情重複很多次,比如說for循環

for迴圈可以對一切有iter方法的物件進行迭代,那麼什麼是iter方法呢?

一個物件是否可迭代,全都取決於這個物件是否有iter方法,呼叫物件的iter方法,就回回傳一個迭代器,這個迭代器一定有next方法,在當呼叫這個迭代器的next方法時,迭代器就回回它的下一個值,當迭代器中沒有值可以回傳了,就回拋出一個名為StopIteration的異常,停止迭代。

迭代器還有個很重要的特性,就是不可逆,只能前進,不能後退。

for迴圈就是這樣運作的,for迴圈在迴圈一個物件的時候,會呼叫這個物件的iter方法,得到迭代器,然後在呼叫這個迭代器的next方法,去得到這個迭代器中包涵的每個值。

二.列表和迭代器的差別在哪裡?如何可以實作一個基本的迭代器?

迭代器的工作方式,是在使用的時候計算一個值來取得一個值,而列表呢,是一次性取得所有的值,如果有很多值,就會佔用很大的記憶體。

當自己建立一個物件時,如何讓自己的物件可迭代?

class test_class:

    def init(self,start_num,stop_num):

#    def init(self,start_num,stop_num):

#    self.start_num = start_num

#      self.start_num stop_num = stop_num

    def next(self):

       

if

self.start_num <  self.stop_num:

# . ##        return

self.start_num

    def iter(self):

        return self

##test_obj = test_class(0,0333)

print test_obj.next()

>>>1

print test_obj.next()

#> >>2

print test_obj.next()

>>>3

三.什麼是產生器

個人的理解,生成器是個比較特殊的可迭代對象,它與其他的可迭代對像不太一樣的地方,就是,其他的可迭代對象需要調用iter方法,返回個迭代器對象,然後透過迭代器物件去執行next方法,取得迭代器中的值,但是生成器直接可以被迭代,無需執行iter方法。

python中產生器有兩種表達式:

函數式產生器:也就是字面上,在常規的函數中定義的生成器,語句的返回值不再使用return去返回,而是使用yield關鍵字每次返回一個結果,一個函數中不可以有多個return,但是可以有多個yield,函數中的每一個yield都會回傳一個結果,每執行一個yield,函數的執行狀態都會被'掛起'可以理解為暫停,下次繼續呼叫這個函數的時候,會從上次掛起的位置繼續向下執行。

下面是關於函數式產生器的範例:

下面這個例子驗證了yield的兩個特性,第一個是一個函數可以yield多個值,有多個yield,另外一個就是函數式產生器的掛起特性。

def func1():

    yield 1

    print "第一個yield執行完成~"

#    yield 2

#  # 

##    yield 2

#  # "第二個yield執行完成~"

    yield 3

    print "第三個yield執行完成~"

for i in func1():

    print i

>>>1

       第一個yield執行完成~

      2

## 

      3

       第三個yield執行完成~產生器

表達式

:使用類似清單推導式的方法,但是傳回的物件不再是一個列表,而是一個可以按需產生結果的一個物件(生成器)。

       例1:        for i in (i for i in

range###(10000)):###

            print i

#(i for i in range(5)) 這個是產生器運算式。

(i for i in range(10000)) =  def test(): for i in range(10000):yield i

這兩個種寫法起到的作用是一樣的,只不過是寫法不同,一個是生成器表達式,另一個是函數式產生器。

有沒有覺得這種生成器表達式和列表推導式看起來很像,不同的地方就在於列表推導式是使用[]中括號,而生成器表達式使用的是()小括號?

事實就是如此,它們之間的語法確實只差一個括號,但是,生成器表達式更節省記憶體空間。

關於生成器,大致就說的差不多了,最後來個總結:

生成器的定義方法與普通的函數是一模一樣的,不同的地方就是生成器使用yield返回一個值,函數使用return回傳一個值。

在python中,生成器會自動實作迭代協議,在沒有值可以回傳的時候,回傳一個StopIteration異常。

產生器使用yield語句傳回一個值。 yield語句掛起該生成器函數的狀態,保留足夠的訊息,以便之後從它離開的地方繼續執行。

下面的範例是清單推導式和產生器運算式執行的效率對比,有興趣的小夥伴可以在自己電腦上執行一下試試看。

#列表解析

sum([i for i in range(100000000)])#記憶體佔用大,機器容易卡死

#產生器表達式

sum(i for i in range(100000000))#幾乎不佔記憶體

以上是python迭代器與生成器的詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn