Python之itertools模塊

圖片匯總:



ITERTOOLS是一個高效循環(huán)的迭代函數(shù)集合疫铜。正好在最近的應(yīng)用的時(shí)候用的比較多,網(wǎng)上幾個比較詳細(xì)的介紹帖子要么寫的抽象,要么例子不夠簡潔岁钓。就大概整理了一下,搬運(yùn)成分偏少微王。反正不重復(fù)造輪子是一個比較pythonic的原則屡限,所以有空就分享一下。不過個人推薦有空還是可以看一下這些內(nèi)建函數(shù)本身的實(shí)現(xiàn)源碼炕倘,都非常簡潔钧大。


一、組成
itertools主要來分為三類函數(shù)罩旋,分別為無限迭代器拓型、輸入序列迭代器、組合生成器瘸恼,我們下面開始具體講解劣挫。


二、無限迭代器
1东帅、Itertools.count(start=0, step=1)
創(chuàng)建一個迭代對象压固,生成從start開始的連續(xù)整數(shù),步長為step靠闭。
如果省略了start則默認(rèn)從0開始帐我,步長默認(rèn)為1
如果超過了sys.maxint,則會移除并且從-sys.maxint-1開始計(jì)數(shù)愧膀。

    例:
    from itertools import *
    for i in izip(count(2,6), ['a', 'b', 'c']):
    print i
    輸出為:
    (2, 'a')
    (8, 'b')
    (14, 'c')

2拦键、Itertools.cycle(iterable)
創(chuàng)建一個迭代對象,對于輸入的iterable的元素反復(fù)執(zhí)行循環(huán)操作檩淋,內(nèi)部生成iterable中的元素的一個副本芬为,這個副本用來返回循環(huán)中的重復(fù)項(xiàng)。

    例:
    from itertools import *
    i = 0
    for item in cycle(['a', 'b', 'c']):
        i += 1
        if i == 10:
            break
        print (i, item)
    輸出為:
    (1, 'a')
    (2, 'b')
    (3, 'c')
    (4, 'a')    
    (5, 'b')
    (6, 'c')
    (7, 'a')
    (8, 'b')
    (9, 'c')

3蟀悦、Itertools.repeat(object[, times])
創(chuàng)建一個迭代器媚朦,重復(fù)生成object,如果沒有設(shè)置times日戈,則會無線生成對象询张。

    例:
    from itertools import *
    for i in repeat('kivinsae', 5):
        print I
    輸出為:
    kivinsae
    kivinsae
    kivinsae
    kivinsae
    kivinsae

三、輸入序列迭代器
1浙炼、itertools.accumulate(*iterables)
這個函數(shù)簡單來說就是一個累加器份氧,不停對列表或者迭代器進(jìn)行累加操作(這里指每項(xiàng)累加)唯袄。

 例:
    from itertools import *
    x = itertools.accumulate(range(10))
    print(list(x))
    輸出為:
    [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]

2、itertools.chain(*iterables)
把多個迭代器作為參數(shù)蜗帜,但是只會返回單個迭代器越妈。產(chǎn)生所有參數(shù)迭代器的內(nèi)容,卻好似來自于一個單一的序列钮糖。簡單了講就是連接多個【列表】或者【迭代器】梅掠。

    例:
    from itertools import *
    for i in chain(['p','x','e'], ['scp', 'nmb', 'balenciaga']):
        print I
    輸出為:
    p
    x
    e
    scp
    nmb
    balenciaga

3、itertools.compress(data,selectors)
具體來說compress提供了一個對于原始數(shù)據(jù)的篩選功能店归,具體條件可以設(shè)置的非常復(fù)雜阎抒,所以下面只列出相關(guān)的定義代碼來解釋。不過簡單來理解消痛,就是說按照真值表進(jìn)行元素篩選而已且叁。

    實(shí)現(xiàn)過程:
    def compress(data, selectors):
        # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
        return (d for d, s in izip(data, selectors) if s)    

    例:
    from itertools import compress
    list(compress('ABCDEF', [1, 1, 0, 1, 0, 1]))
    輸出為:
    ['A', 'B', 'D', 'F']

4、itertools.dropwhile(predicate,iterable)
dropwhile作用是創(chuàng)建一個迭代器秩伞,只要是函數(shù)predicate(item)為True逞带,則丟掉iterable中的項(xiàng),但是如果predicate返回的是False纱新,則生成iterable中的項(xiàng)和所有的后續(xù)項(xiàng)展氓。
具體來說就是,在條件為False之后的第一次脸爱,就返回迭代器中剩余的所有項(xiàng)遇汞。在這個函數(shù)表達(dá)式里面iterable的值會按索引一個個作為predicate的參數(shù)進(jìn)行計(jì)算。
簡單來說其實(shí)就是按照真值函數(shù)丟棄掉列表和迭代器前面的元素簿废。

    例:
    from itertools import *
    def should_drop(x):
        print 'Testing:', x
        return (x<1)
    for i in dropwhile(should_drop, [ -1, 0, 1, 2, 3, 4, 1, -2 ]):
        print 'Yielding:', i
    輸出為:
    Testing: -1
    Testing: 0
    Testing: 1
    Yielding: 1
    Yielding: 2
    Yielding: 3
    Yielding: 4
    Yielding: 1
    Yielding: -2

5空入、itertools.groupby(iterable[,key])
返回一個集合的迭代器,集合內(nèi)是按照key進(jìn)行分組后的值族檬。
如果iterable在多次連續(xù)的迭代中生成了同一項(xiàng)歪赢,則會定義一個組,如果對這個函數(shù)應(yīng)用一個分類列表单料,那么分組會定義這個列表中所有的唯一項(xiàng)埋凯,key是一個函數(shù)并應(yīng)用于每一項(xiàng)。如果這個函數(shù)有返回值看尼,則這個值會用于后續(xù)的項(xiàng)递鹉,而不是和該項(xiàng)本身進(jìn)行比較盟步。這個函數(shù)返回的迭代器生成元素(key,group)藏斩,key是分組的鍵值,group是迭代器却盘,從而生成組成這個組的所有項(xiàng)目狰域。

具體來說實(shí)現(xiàn)過程和示例如下:
    實(shí)現(xiàn)過程:
    class groupby(object):
        # [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
        # [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
        def __init__(self, iterable, key=None):
            if key is None:
                key = lambda x: x
            self.keyfunc = key
            self.it = iter(iterable)
            self.tgtkey = self.currkey = self.currvalue = object()
        def __iter__(self):
            return self
        def next(self):
            while self.currkey == self.tgtkey:
                self.currvalue = next(self.it)    # Exit on StopIteration
                self.currkey = self.keyfunc(self.currvalue)
            self.tgtkey = self.currkey
            return (self.currkey, self._grouper(self.tgtkey))
        def _grouper(self, tgtkey):
            while self.currkey == tgtkey:
                yield self.currvalue
                self.currvalue = next(self.it)    # Exit on StopIteration
                self.currkey = self.keyfunc(self.currvalue)

    例:
    from itertools import *
    a = ['aa', 'ab', 'abc', 'bcd', 'abcde']
    for i, k in groupby(a, len):
        print i, list(k)
    輸出為:
    2 ['aa', 'ab']
    3 ['abc', 'bcd']
    5 ['abcde']

6媳拴、itertools.ifilter(predicate,iterable)
本函數(shù)返回一個迭代器,類似于針對于列表的函數(shù)filter()兆览,但是只包括測試函數(shù)返回True時(shí)候的值屈溉。和dropwhile()作用不同。
函數(shù)創(chuàng)建一個迭代器抬探,只生成predicate(iterable)為True的項(xiàng)子巾,簡單來說就是返回iterable中所有計(jì)算后為True的項(xiàng)。如果是非True則進(jìn)行之后的其他操作小压。

    例:
    from itertools import *
    def check_item(x):
        print 'Testing:', x
        return (x<1)
    for i in ifilter(check_item, [ -1, 0, 1, 2, 3, 4, 1, -2 ]):
        print 'Yielding:', i
    輸出為:
    Testing: -1
    Yielding: -1
    Testing: 0
    Yielding: 0
    Testing: 1
    Testing: 2
    Testing: 3
    Testing: 4
    Testing: 1
    Testing: -2
    Yielding: -2

7线梗、itertools.ifilterfalse(predicate,iterable)
本函數(shù)和上面的ifilter一樣,唯一的區(qū)別是只有當(dāng)predicate(iterable)為False時(shí)候才進(jìn)行predicate的輸出怠益。

    例:
    from itertools import *
    def check_item(x):
        print 'Testing:', x
        return (x<1)
    for i in ifilterfalse(check_item, [ -1, 0, 1, 2, 3, 4, 1, -2 ]):
        print 'Yielding:', I
    輸出為:
    Testing: -1
    Testing: 0
    Testing: 1
    Yielding: 1
    Testing: 2
    Yielding: 2
    Testing: 3
    Yielding: 3
    Testing: 4
    Yielding: 4
    Testing: 1
    Yielding: 1
    Testing: -2

8仪搔、itertools.islice(iterable,stop)
簡單來說這個函數(shù),就是對于一個迭代對象iterable蜻牢,設(shè)定一個特定的切片/選取/截取規(guī)則烤咧,然后最后輸出一個特定的新的迭代對象的過程。這個stop實(shí)際上代表一個三元數(shù)組抢呆,也就是start煮嫌,stop,step抱虐。如果start省略立膛,默認(rèn)從索引0開始;如果step被省略梯码,則默認(rèn)步長為1宝泵;stop不能被省略。本質(zhì)就是一個切片工具轩娶。

    例:
    from itertools import *
    print 'Stop at 5:'
    for i in islice(count(), 5):
        print i
    
    print 'Start at 5, Stop at 10:'
    for i in islice(count(), 5, 10):
        print i
    print 'By tens to 100:'
    for i in islice(count(), 0, 100, 10):
        print I
    輸出為:
    Stop at 5:
    0
    1
    2
    3
    4
    Start at 5, Stop at 10:
    5
    6
    7
    8
    9
    By tens to 100:
    0
    10
    20
    30
    40
    50
    60
    70
    80
    90

9儿奶、itertools.imap(function,*iterable)
本函數(shù)創(chuàng)建一個迭代器,作用函數(shù)為function1鳄抒,function2闯捎,function3…,對應(yīng)的變量來自迭代器iterable1许溅,iterable2瓤鼻,iterable3…。然后返回一個(f1,f2,f3…)形式的元組贤重。只要其中一個迭代器不再生成值茬祷,這個函數(shù)就會停止。所以要處理好None的情況并蝗,用一下替代輸出之類的方法祭犯。

    例:
    from itertools import *
    print 'Doubles:'
    for i in imap(lambda x:2*x, xrange(5)):
        print i
    print 'Multiples:'
    for i in imap(lambda x,y:(x, y, x*y), xrange(5), xrange(5,10)):
        print '%d * %d = %d' % I
    輸出為:
    Doubles:
    0
    2
    4
    6
    8
    Multiples:
    0 * 5 = 0
    1 * 6 = 6
    2 * 7 = 14
    3 * 8 = 24
    4 * 9 = 36

10秸妥、itertools.starmap(function,iterable)
本函數(shù)創(chuàng)建一個函數(shù),其中內(nèi)調(diào)用的function(*item)沃粗,item來自于iterable粥惧。只有當(dāng)?shù)鷮ο骾terable生成的項(xiàng)適合這個函數(shù)的調(diào)用形式的時(shí)候,starmap才會有效最盅。

    例:
    from itertools import *
    values = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)]
    for i in starmap(lambda x,y:(x, y, x*y), values):
        print '%d * %d = %d' % I
    輸出為:
    0 * 5 = 0
    1 * 6 = 6
    2 * 7 = 14
    3 * 8 = 24
    4 * 9 = 36

11突雪、itertools.tee(iterable[,n=2])
這個函數(shù)會返回若干個基于某個原始輸入的獨(dú)立迭代器。類似于Linux系統(tǒng)上的tee指令涡贱。如果不特地制定n的話挂签,函數(shù)會默認(rèn)是2。tee括號里面最好使用標(biāo)準(zhǔn)輸入盼产,而不是原始迭代器饵婆。不然會在某些緩存過程中出現(xiàn)異常。

    例:
    from itertools import *
    r = islice(count(), 5)
    i1, i2 = tee(r)
    for i in i1:
        print 'i1:', i
    for i in i2:
        print 'i2:', I
    輸出為:
    i1: 0
    i1: 1
    i1: 2
    i1: 3
    i1: 4
    i2: 0
    i2: 1
    i2: 2
    i2: 3
    i2: 4

12戏售、itertools.takewhile(predicate,iterable)
這個函數(shù)和dropwhile剛好相反侨核,只要predicate計(jì)算后為False,迭代過程立刻停止灌灾。

    例:
    from itertools import *
    def should_take(x):
        print 'Testing:', x
        return (x<2)
    for i in takewhile(should_take, [ -1, 0, 1, 2, 3, 4, 1, -2 ]):
        print 'Yielding:', I
    輸出為:
    Testing: -1
    Yielding: -1
    Testing: 0
    Yielding: 0
    Testing: 1
    Yielding: 1
    Testing: 2

13搓译、itertools.izip( *iterables)
這個函數(shù)返回一個合并多個迭代器,成為一個元組的迭代對象锋喜。類似于內(nèi)置函數(shù)zip些己,但返回的是迭代對象而非列表。
創(chuàng)建一個迭代對象嘿般,生成元組(i1,i2,i3…)分別來自于i1,i2,i3…段标,只要提供的某個迭代器不在生成值,函數(shù)就會立刻停止炉奴。

    例:
    from itertools import *
    for i in izip([1, 2, 3], ['a', 'b', 'c']):
        print I
    輸出為:
    (1, 'a')
    (2, 'b')
    (3, 'c')

14逼庞、itertools.izip_longest(*iterable[,fillvalue])
本函數(shù)和izip雷同,但是區(qū)別在于不會停止瞻赶,會把所有輸入的迭代對象全部耗盡為止赛糟,對于參數(shù)不匹配的項(xiàng),會用None代替砸逊。非常容易理解璧南。

    例:
    from itertools import *
    for i in izip_longest([1, 2, 3], ['a', 'b']):
        print I
    輸出為:
    (1, 'a')
    (2, 'b')
    (3, None)

四、組合生成器
1师逸、itertools.product(*iterable[,repeat])
這個工具就是產(chǎn)生多個列表或者迭代器的n維積司倚。如果沒有特別指定repeat默認(rèn)為列表和迭代器的數(shù)量。

    例:
    import itertools
    a = (1, 2, 3)
    b = ('A', 'B', 'C')
    c = itertools.product(a,b)
    for elem in c:
        print elem
    輸出為:
    (1, 'A')
    (1, 'B')
    (1, 'C')
    (2, 'A')
    (2, 'B')
    (2, 'C')
    (3, 'A')
    (3, 'B')
    (3, 'C')

2、itertools.permutations(iterable[,r])
這個函數(shù)作用其實(shí)就是產(chǎn)生指定數(shù)目repeat的元素的所有排列对湃,且順序有關(guān)崖叫,但是遇到原列表或者迭代器有重復(fù)元素的現(xiàn)象的時(shí)候遗淳,也會對應(yīng)的產(chǎn)生重復(fù)項(xiàng)拍柒。這個時(shí)候最好用groupby或者其他filter去一下重,如果有需要的話屈暗。

    例:
    import itertools
    x = itertools.permutations(range(4), 3)
    print(list(x))
    輸出為:
    [(0, 1, 2), 
    (0, 1, 3), 
    (0, 2, 1), 
    (0, 2, 3), 
    (0, 3, 1), 
    (0, 3, 2), 
    (1, 0, 2), 
    (1, 0, 3), 
    (1, 2, 0), 
    (1, 2, 3), 
    (1, 3, 0), 
    (1, 3, 2), 
    (2, 0, 1), 
    (2, 0, 3), 
    (2, 1, 0), 
    (2, 1, 3), 
    (2, 3, 0), 
    (2, 3, 1), 
    (3, 0, 1),
    (3, 0, 2), 
    (3, 1, 0), 
    (3, 1, 2), 
    (3, 2, 0), 
    (3, 2, 1)
    ]

3拆讯、itertools.combinations(iterable,r)
這個函數(shù)用來生成指定數(shù)目r的元素不重復(fù)的所有組合。注意和permutation的區(qū)分养叛,以及這個組合是無序的种呐,只考慮元素本身的unique性。

    例:
    import itertools
    x = itertools.combinations(range(4), 3)
    print(list(x))
    輸出為:
    [(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)]

4弃甥、itertools.combinations_with_replacement(iterable,r)
這個函數(shù)用來生成指定數(shù)目r的元素可重復(fù)的所有組合爽室。然而這個函數(shù)依然要保證元素組合的unique性。

    例:
    import itertools
    x = itertools.combinations_with_replacement('ABC', 2)
    print(list(x))
    輸出為:
    [('A', 'A'), 
    ('A', 'B'), 
    ('A', 'C'), 
    ('B', 'B'), 
    ('B', 'C'), 
    ('C', 'C’)
    ]

選自:http://www.reibang.com/p/73b17486ef8c

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末淆攻,一起剝皮案震驚了整個濱河市阔墩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瓶珊,老刑警劉巖啸箫,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異伞芹,居然都是意外死亡忘苛,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門唱较,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扎唾,“玉大人,你說我怎么就攤上這事南缓』粒” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵西乖,是天一觀的道長狐榔。 經(jīng)常有香客問我,道長获雕,這世上最難降的妖魔是什么薄腻? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮届案,結(jié)果婚禮上庵楷,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好尽纽,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布咐蚯。 她就那樣靜靜地躺著,像睡著了一般弄贿。 火紅的嫁衣襯著肌膚如雪春锋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天差凹,我揣著相機(jī)與錄音期奔,去河邊找鬼。 笑死危尿,一個胖子當(dāng)著我的面吹牛呐萌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谊娇,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼肺孤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了济欢?” 一聲冷哼從身側(cè)響起赠堵,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎船逮,沒想到半個月后顾腊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡挖胃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年杂靶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酱鸭。...
    茶點(diǎn)故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡吗垮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出凹髓,到底是詐尸還是另有隱情烁登,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布蔚舀,位于F島的核電站饵沧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏赌躺。R本人自食惡果不足惜狼牺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望礼患。 院中可真熱鬧是钥,春花似錦掠归、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至弹囚,卻和暖如春厨相,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背余寥。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工领铐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留悯森,地道東北人宋舷。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像瓢姻,于是被迫代替她去往敵國和親祝蝠。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容

  • PYTHON-進(jìn)階-ITERTOOLS模塊小結(jié)轉(zhuǎn)自wklken:http://wklken.me/posts/20...
    C_Y_閱讀 974評論 0 2
  • ITERTOOLS是一個高效循環(huán)的迭代函數(shù)集合幻碱。正好在最近的應(yīng)用的時(shí)候用的比較多绎狭,網(wǎng)上幾個比較詳細(xì)的介紹帖子要么寫...
    kivinsae閱讀 3,016評論 1 10
  • 在復(fù)習(xí)Python基本語法的時(shí)候,看到了迭代器模塊褥傍,做一個簡單的筆記儡嘶。 Iterable: 所謂可迭代數(shù)據(jù)流,即能...
    idok閱讀 441評論 0 0
  • 繁華夜的街道 步履蹣跚 微涼風(fēng)的方向 和我一樣 穿過暮光的山 驚醒夢的殘章 誰人哭喊 誰人離傷 誰人又一去不返 倒...
    方塊陳糖閱讀 115評論 0 0
  • 五天前還在一起擁抱親吻恍风,五天后杳無音信 喜歡一個人蹦狂,不只是因?yàn)樗麑ξ液茫撬褪撬蟊幔矚g他的堅(jiān)持凯楔,喜歡他的自律,...
    fairy小瘦閱讀 45評論 0 0