久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

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

 天上飛雞 2020-09-25

作者:豌豆花下貓

來自:Python貓 

鏈接:https://mp.weixin.qq.com/s/7MbRCn37fIIN42rLm6ho3g

在軟件開發(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)用迭代器的場(chǎng)景等等,期待與你共同學(xué)習(xí)進(jìn)步,。

1、什么是迭代器模式?

維基百科有如下定義:

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

簡(jiǎ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<String> list = new ArrayList<>();
Iterator<String> 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)寫法簡(jiǎn)便,用意直白,;(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)化為迭代器的簡(jiǎn)易方法,如此安排,,真是將迭代器模式的效力發(fā)揮到了極致,。

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() 等等,。

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

3.1 無限迭代器

count(start=0, step=1) :創(chuàng)建一個(gè)從 start (默認(rèn)值為 0) 開始,,以 step (默認(rèn)值為 1) 為步長(zhǎng)的的無限整數(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() 方法返回迭代器切片,;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', [110101]):
    print(c,end=' ')
# 輸出結(jié)果:A B D F

for keygroup 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é)果:(<itertools._tee at 0x1fc72c08108>,
 <itertools._tee at 0x1fc73f91d08>,
 <itertools._tee at 0x1fc73efc248>)

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)置迭代器方法

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

4.1 zip() 方法

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

import itertools

a = [123]
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í),,迭代長(zhǎng)度等于較短對(duì)象的長(zhǎng)度,。

def square(x):
    return x ** 2

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

m = map(lambda x, y: x + y, [13579], [2468102])
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)置方法。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多