国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Python進(jìn)階:設(shè)計(jì)模式之迭代器模式

pubdreamcc / 618人閱讀

摘要:抓住了迭代器模式的本質(zhì),即是迭代,賦予了它極高的地位。輸出結(jié)果輸出結(jié)果小結(jié)迭代器模式幾乎是種設(shè)計(jì)模式中最常用的設(shè)計(jì)模式,本文主要介紹了是如何運(yùn)用迭代器模式,并介紹了模塊生成迭代器的種方法,以及種生成迭代器的內(nèi)置方法。

在軟件開發(fā)領(lǐng)域中,人們經(jīng)常會(huì)用到這一個(gè)概念——“設(shè)計(jì)模式”(design pattern),它是一種針對(duì)軟件設(shè)計(jì)的共性問題而提出的解決方案。在一本圣經(jīng)級(jí)的書籍《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》(1991年,Design Patterns - Elements of Reusable Object-Oriented Software)中,它提出了23種設(shè)計(jì)模式。迭代器模式就是其中的一種,在各種編程語言中都得到了廣泛的應(yīng)用。

本文將談?wù)?Python 中的迭代器模式,主要內(nèi)容:什么是迭代器模式、Python 如何實(shí)現(xiàn)迭代器模式、itertools 模塊創(chuàng)建迭代器的方法、其它運(yùn)用迭代器的場景等等,期待與你共同學(xué)習(xí)進(jìn)步。

1、什么是迭代器模式?

維基百科有如下定義:

迭代器是一種最簡單也最常見的設(shè)計(jì)模式。它可以讓用戶透過特定的接口巡訪容器中的每一個(gè)元素而不用了解底層的實(shí)現(xiàn)。——維基百科

簡單地說,迭代器模式就是一種通用性的可以遍歷容器類型(如序列類型、集合類型等)的實(shí)現(xiàn)方式。使用迭代器模式,可以不關(guān)心遍歷的對(duì)象具體是什么(如字符串、列表、字典等等),也不需要關(guān)心遍歷的實(shí)現(xiàn)算法是什么,它關(guān)心的是從容器中遍歷/取出元素的結(jié)果。

按遍歷方式劃分,迭代器可分為內(nèi)部迭代器與外部迭代器,它們的區(qū)別在于執(zhí)行迭代動(dòng)作與維持迭代狀態(tài)的不同。

通常而言,迭代器是一次性的,當(dāng)?shù)^一輪后,再次迭代將獲取不到元素。

2、Python的迭代器模式

由于迭代器模式的使用太常見了,所以大多數(shù)編程語言都給常見的容器類型實(shí)現(xiàn)了它,例如 Java 中的 Collection,List、Set、Map等。在 Java 中使用迭代器遍歷 List 可以這么寫:

List list = new ArrayList<>();
Iterator iterator = list.iterator();
while(iterator.hasNext()){
    System.out.println(iterator.next());
}

ArrayList 類通過自身的 iterator() 方法獲得一個(gè)迭代器 iterator,然后由該迭代器實(shí)例來落實(shí)遍歷過程。

Python 當(dāng)然也應(yīng)用了迭代器模式,但它的實(shí)現(xiàn)思路跟上例卻不太一樣。

首先,Python 認(rèn)為遍歷容器類型并不一定要用到迭代器,因此設(shè)計(jì)了可迭代對(duì)象。

list = [1,2,3,4]
for i in list:
    print(i,end=" ") # 1 2 3 4
for i in list:
    print(i,end=" ") # 1 2 3 4

上例中的 list 是可迭代對(duì)象(Iterable),但并不是迭代器(雖然在底層實(shí)現(xiàn)時(shí)用了迭代器的部分思想)。Python 抓住了迭代器模式的本質(zhì),即是“迭代”,賦予了它極高的地位。

如此設(shè)計(jì)的好處顯而易見:(1)寫法簡便,用意直白;(2)可重復(fù)迭代,避免一次性迭代器的缺陷;(3)不需要?jiǎng)?chuàng)建迭代器,減少開銷。

可迭代對(duì)象可看作是廣義的迭代器,同時(shí),Python 也設(shè)計(jì)了普通意義的狹義的迭代器。

list = [1,2,3,4]
it = iter(list)
for i in it:
    print(i,end=" ") # 1 2 3 4
for i in it:
    print(i,end=" ") # 無輸出

上例中的 iter() 方法會(huì)將可迭代對(duì)象變成一個(gè)迭代器。從輸出結(jié)果可以看出,該迭代器的迭代過程是一次性的。

由此看來,Python 其實(shí)是將“迭代器模式”一拆為二來實(shí)現(xiàn):一是可迭代思想,廣泛播種于容器類型的對(duì)象中,使它們都可迭代;一是迭代器,一種特殊的可迭代對(duì)象,承擔(dān)普通意義上的迭代器所特有的迭代任務(wù)。

同時(shí),它還提供了將可迭代對(duì)象轉(zhuǎn)化為迭代器的簡易方法,如此安排,真是將迭代器模式的效力發(fā)揮到了極致。(關(guān)于可迭代對(duì)象與迭代器的更多區(qū)別、以及它們的實(shí)現(xiàn)原理,請(qǐng)參見《Python進(jìn)階:迭代器與迭代器切片》)

3、創(chuàng)建迭代器

創(chuàng)建迭代器有如下方式:(1)iter() 方法,將可迭代對(duì)象轉(zhuǎn)化成迭代器;(2)__iter__()__next__() 魔術(shù)方法,定義類實(shí)現(xiàn)這兩個(gè)魔術(shù)方法;(3)itertools 模塊,使用內(nèi)置模塊生成迭代器;(4)其它創(chuàng)建方法,如 zip() 、map() 、enumerate() 等等。

四類方法各有適用場所,本節(jié)重點(diǎn)介紹 itertools 模塊。它可以創(chuàng)建三類迭代器:無限迭代器、有限迭代器與組合迭代器。

3.1 無限迭代器

count(start=0, step=1) :創(chuàng)建一個(gè)從 start (默認(rèn)值為 0) 開始,以 step (默認(rèn)值為 1) 為步長的的無限整數(shù)迭代器。

cycle(iterable) :對(duì)可迭代對(duì)象的元素反復(fù)執(zhí)行循環(huán)。

repeat(object [,times]) :反復(fù)生成 object 至無限,或者到給定的 times 次。

import itertools
co = itertools.count()
cy = itertools.cycle("ABC")
re = itertools.repeat("A", 30)

# 注意:請(qǐng)分別執(zhí)行;以下寫法未加終止判斷,只能按 Ctrl+C 退出
for n in co:
    print(n,end=" ")  # 0 1 2 3 4......
for n in cy:
    print(n,end=" ")  # A B C A B C A B......
for n in re:
    print(n,end=" ")  # A A A A A A A A....(30個(gè))
3.2 有限迭代器

以上方法,比較常用的有:chain() 將多個(gè)可迭代對(duì)象(可以是不同類型)連接成一個(gè)大迭代器;compress() 方法根據(jù)真假過濾器篩選元素;groupby() 把迭代器中相鄰的重復(fù)元素挑出來放在一起;islice() 方法返回迭代器切片(用法參見《Python進(jìn)階:迭代器與迭代器切片》);tee() 方法根據(jù)可迭代對(duì)象創(chuàng)建 n 個(gè)(默認(rèn)2個(gè))迭代器副本。

for c in itertools.chain("ABC", [1,2,3]):
    print(c,end=" ")
# 輸出結(jié)果:A B C 1 2 3

for c in itertools.compress("ABCDEF", [1, 1, 0, 1, 0, 1]):
    print(c,end=" ")
# 輸出結(jié)果:A B D F

for key, group in itertools.groupby("aaabbbaaccd"):
    print(key, ":", list(group))
# 輸出結(jié)果:
a : ["a", "a", "a"]
b : ["b", "b", "b"]
a : ["a", "a"]
c : ["c", "c"]
d : ["d"]

itertools.tee("abc", 3)
# 輸出結(jié)果:(,
 ,
 )
3.3 組合迭代器

product() :求解多個(gè)可迭代對(duì)象的笛卡爾積。

permutations() :求解可迭代對(duì)象的元素的全排列。

combinations():求解可迭代對(duì)象的元素的組合。

for i in itertools.product("ABC", [1,2]):
    print(i, end=" ")
# 輸出結(jié)果:("A", 1) ("A", 2) ("B", 1) ("B", 2) ("C", 1) ("C", 2)

for i in itertools.permutations("ABC", 2):
    print(i, end=" ")
# 輸出結(jié)果:("A", "B") ("A", "C") ("B", "A") ("B", "C") ("C", "A") ("C", "B")

for i in itertools.combinations("ABC", 2):
    print(i, end=" ")
# 輸出結(jié)果:("A", "B") ("A", "C") ("B", "C")

for i in itertools.combinations("ABCD", 3):
    print(i, end=" ")
# 輸出結(jié)果:("A", "B", "C") ("A", "B", "D") ("A", "C", "D") ("B", "C", "D")
4、強(qiáng)大的內(nèi)置迭代器方法

迭代器模式的使用場景實(shí)在太普遍了,而 Python 也為迭代器的順利使用而提供了很多便利的條件,本節(jié)將介紹相關(guān)的幾個(gè)內(nèi)置方法。這些方法非常常用而且強(qiáng)大,是 Python 進(jìn)階的必會(huì)內(nèi)容。

4.1 zip() 方法

zip() 方法可以同時(shí)迭代多個(gè)序列,并各取一個(gè)元素,生成一個(gè)可返回元組的迭代器。此迭代器的長度以較短序列的長度保持一致,若想生成較長序列的長度,需要使用 itertools 模塊的 zip_longest() 方法。

import itertools

a = [1, 2, 3]
b = ["w", "x", "y", "z"]

for i in zip(a,b):
    print(i,end=" ")  # (1, "w") (2, "x") (3, "y")

# 空缺值以 None 填補(bǔ)
for i in itertools.zip_longest(a,b):
    print(i,end=" ")  # (1, "w") (2, "x") (3, "y") (None, "z")
4.2 enumerate() 方法

enumerate() 方法接收一個(gè)序列類型參數(shù),生成一個(gè)可返回元組的迭代器,元組內(nèi)容是下標(biāo)及其對(duì)應(yīng)的元素值。它還可接收一個(gè)可選參數(shù),指定下標(biāo)的起始值,默認(rèn)是0 。

注意:眾所周知,Python 中序列的索引值從 0 開始,但是,enumerate() 可以達(dá)到改變起始索引數(shù)值的效果。

seasons = ["Spring", "Summer", "Fall", "Winter"]

for i in enumerate(seasons):
    print(i,end=" ")  
#輸出結(jié)果:(0, "Spring") (1, "Summer") (2, "Fall") (3, "Winter")

for i in enumerate(seasons, start=7):
    print(i,end=" ")  
#輸出結(jié)果:(7, "Spring") (8, "Summer") (9, "Fall") (10, "Winter")
4.3 map() 方法

map() 方法的參數(shù)是一個(gè)函數(shù)及一個(gè)或多個(gè)可迭代對(duì)象,它會(huì)將可迭代對(duì)象的元素映射到該函數(shù)中,然后迭代地運(yùn)行該函數(shù),返回結(jié)果也是一個(gè)迭代器。當(dāng)存在多個(gè)可迭代對(duì)象參數(shù)時(shí),迭代長度等于較短對(duì)象的長度。

def square(x):
    return x ** 2

l = map(square, [1, 2, 3, 4, 5])
print(list(l))
# 輸出結(jié)果:[1, 4, 9, 16, 25]

m = map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10, 2])
print(list(m))
# 輸出結(jié)果:[3, 7, 11, 15, 19]
4.4 filter() 方法

filter() 方法的參數(shù)是一個(gè)判斷函數(shù)及一個(gè)可迭代對(duì)象,遍歷可迭代對(duì)象執(zhí)行判斷函數(shù),過濾下判斷為True 的元素,與它相對(duì),若想保留判斷為 False 的元素,可使用 itertoole 模塊的 filterfalse() 方法。

import itertools

fi = filter(lambda x: x%2, range(10))
ff = itertools.filterfalse(lambda x: x%2, range(10))

for i in fi:
    print(i,end=" ")
# 輸出結(jié)果:1 3 5 7 9

for i in ff:
    print(i,end=" ")
# 輸出結(jié)果:0 2 4 6 8
5. 小結(jié)

迭代器模式幾乎是 23 種設(shè)計(jì)模式中最常用的設(shè)計(jì)模式,本文主要介紹了 Python 是如何運(yùn)用迭代器模式,并介紹了 itertools 模塊生成迭代器的 18 種方法,以及 5 種生成迭代器的內(nèi)置方法。

相關(guān)鏈接:

itertools模塊文檔:http://t.cn/R6cGtfw

Python進(jìn)階:迭代器與迭代器切片

Python進(jìn)階:全面解讀高級(jí)特性之切片!

-----------------

本文原創(chuàng)并首發(fā)于微信公眾號(hào)【Python貓】,后臺(tái)回復(fù)“愛學(xué)習(xí)”,免費(fèi)獲得20+本精選電子書。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/25047.html

相關(guān)文章

  • Python進(jìn)階設(shè)計(jì)模式迭代模式

    摘要:抓住了迭代器模式的本質(zhì),即是迭代,賦予了它極高的地位。輸出結(jié)果輸出結(jié)果小結(jié)迭代器模式幾乎是種設(shè)計(jì)模式中最常用的設(shè)計(jì)模式,本文主要介紹了是如何運(yùn)用迭代器模式,并介紹了模塊生成迭代器的種方法,以及種生成迭代器的內(nèi)置方法。 showImg(https://segmentfault.com/img/bVbmv7W?w=4272&h=2848); 在軟件開發(fā)領(lǐng)域中,人們經(jīng)常會(huì)用到這一個(gè)概念——設(shè)...

    sherlock221 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<