摘要:的使用形式和類似,它將中為的元素組成一個迭代器返回,如果是,則返回中所有計算為的項。用于將多個可迭代對象對應位置的元素作為一個元組,將所有元組組成一個迭代器,并返回。
itertools
我們知道,迭代器的特點是:惰性求值(Lazy evaluation),即只有當迭代至某個值時,它才會被計算,這個特點使得迭代器特別適合于遍歷大文件或無限集合等,因為我們不用一次性將它們存儲在內存中。
Python 內置的 itertools 模塊包含了一系列用來產生不同類型迭代器的函數或類,這些函數的返回都是一個迭代器,我們可以通過 for 循環來遍歷取值,也可以使用 next() 來取值。
itertools 模塊提供的迭代器函數有以下幾種類型:
無限迭代器:生成一個無限序列,比如自然數序列 1, 2, 3, 4, ...;
有限迭代器:接收一個或多個序列(sequence)作為參數,進行組合、分組和過濾等;
組合生成器:序列的排列、組合,求序列的笛卡兒積等;
無限迭代器itertools 模塊提供了三個函數(事實上,它們是類)用于生成一個無限序列迭代器:
count(firstval=0, step=1)
創建一個從 firstval (默認值為 0) 開始,以 step (默認值為 1) 為步長的的無限整數迭代器
cycle(iterable)
對 iterable 中的元素反復執行循環,返回迭代器
repeat(object [,times]
反復生成 object,如果給定 times,則重復次數為 times,否則為無限
下面,讓我們看看一些例子。
countcount() 接收兩個參數,第一個參數指定開始值,默認為 0,第二個參數指定步長,默認為 1:
>>> import itertools >>> >>> nums = itertools.count() >>> for i in nums: ... if i > 6: ... break ... print i ... 0 1 2 3 4 5 6 >>> nums = itertools.count(10, 2) # 指定開始值和步長 >>> for i in nums: ... if i > 20: ... break ... print i ... 10 12 14 16 18 20cycle
cycle() 用于對 iterable 中的元素反復執行循環:
>>> import itertools >>> >>> cycle_strings = itertools.cycle("ABC") >>> i = 1 >>> for string in cycle_strings: ... if i == 10: ... break ... print i, string ... i += 1 ... 1 A 2 B 3 C 4 A 5 B 6 C 7 A 8 B 9 Crepeat
repeat() 用于反復生成一個 object:
>>> import itertools >>> >>> for item in itertools.repeat("hello world", 3): ... print item ... hello world hello world hello world >>> >>> for item in itertools.repeat([1, 2, 3, 4], 3): ... print item ... [1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4]有限迭代器
itertools 模塊提供了多個函數(類),接收一個或多個迭代對象作為參數,對它們進行組合、分組和過濾等:
chain()
compress()
dropwhile()
groupby()
ifilter()
ifilterfalse()
islice()
imap()
starmap()
tee()
takewhile()
izip()
izip_longest()
chainchain 的使用形式如下:
chain(iterable1, iterable2, iterable3, ...)
chain 接收多個可迭代對象作為參數,將它們『連接』起來,作為一個新的迭代器返回。
>>> from itertools import chain >>> >>> for item in chain([1, 2, 3], ["a", "b", "c"]): ... print item ... 1 2 3 a b c
chain 還有一個常見的用法:
chain.from_iterable(iterable)
接收一個可迭代對象作為參數,返回一個迭代器:
>>> from itertools import chain >>> >>> string = chain.from_iterable("ABCD") >>> string.next() "A"compress
compress 的使用形式如下:
compress(data, selectors)
compress 可用于對數據進行篩選,當 selectors 的某個元素為 true 時,則保留 data 對應位置的元素,否則去除:
>>> from itertools import compress >>> >>> list(compress("ABCDEF", [1, 1, 0, 1, 0, 1])) ["A", "B", "D", "F"] >>> list(compress("ABCDEF", [1, 1, 0, 1])) ["A", "B", "D"] >>> list(compress("ABCDEF", [True, False, True])) ["A", "C"]dropwhile
dropwhile 的使用形式如下:
dropwhile(predicate, iterable)
其中,predicate 是函數,iterable 是可迭代對象。對于 iterable 中的元素,如果 predicate(item) 為 true,則丟棄該元素,否則返回該項及所有后續項。
>>> from itertools import dropwhile >>> >>> list(dropwhile(lambda x: x < 5, [1, 3, 6, 2, 1])) [6, 2, 1] >>> >>> list(dropwhile(lambda x: x > 3, [2, 1, 6, 5, 4])) [2, 1, 6, 5, 4]groupby
groupby 用于對序列進行分組,它的使用形式如下:
groupby(iterable[, keyfunc])
其中,iterable 是一個可迭代對象,keyfunc 是分組函數,用于對 iterable 的連續項進行分組,如果不指定,則默認對 iterable 中的連續相同項進行分組,返回一個 (key, sub-iterator) 的迭代器。
>>> from itertools import groupby >>> >>> for key, value_iter in groupby("aaabbbaaccd"): ... print key, ":", list(value_iter) ... a : ["a", "a", "a"] b : ["b", "b", "b"] a : ["a", "a"] c : ["c", "c"] d : ["d"] >>> >>> data = ["a", "bb", "ccc", "dd", "eee", "f"] >>> for key, value_iter in groupby(data, len): # 使用 len 函數作為分組函數 ... print key, ":", list(value_iter) ... 1 : ["a"] 2 : ["bb"] 3 : ["ccc"] 2 : ["dd"] 3 : ["eee"] 1 : ["f"] >>> >>> data = ["a", "bb", "cc", "ffffd", "eee", "f"] >>> for key, value_iter in groupby(data, len): ... print key, ":", list(value_iter) ... 1 : ["a"] 2 : ["bb", "cc"] 3 : ["ffffd", "eee"] 1 : ["f"]ifilter
ifilter 的使用形式如下:
ifilter(function or None, sequence)
將 iterable 中 function(item) 為 True 的元素組成一個迭代器返回,如果 function 是 None,則返回 iterable 中所有計算為 True 的項。
>>> from itertools import ifilter >>> >>> list(ifilter(lambda x: x < 6, range(10))) [0, 1, 2, 3, 4, 5] >>> >>> list(ifilter(None, [0, 1, 2, 0, 3, 4])) [1, 2, 3, 4]ifilterfalse
ifilterfalse 的使用形式和 ifilter 類似,它將 iterable 中 function(item) 為 False 的元素組成一個迭代器返回,如果 function 是 None,則返回 iterable 中所有計算為 False 的項。
>>> from itertools import ifilterfalse >>> >>> list(ifilterfalse(lambda x: x < 6, range(10))) [6, 7, 8, 9] >>> >>> list(ifilter(None, [0, 1, 2, 0, 3, 4])) [0, 0]islice
islice 是切片選擇,它的使用形式如下:
islice(iterable, [start,] stop [, step])
其中,iterable 是可迭代對象,start 是開始索引,stop 是結束索引,step 是步長,start 和 step 可選。
>>> from itertools import count, islice >>> >>> list(islice([10, 6, 2, 8, 1, 3, 9], 5)) [10, 6, 2, 8, 1] >>> >>> list(islice(count(), 6)) [0, 1, 2, 3, 4, 5] >>> >>> list(islice(count(), 3, 10)) [3, 4, 5, 6, 7, 8, 9] >>> list(islice(count(), 3, 10 ,2)) [3, 5, 7, 9]imap
imap 類似 map 操作,它的使用形式如下:
imap(func, iter1, iter2, iter3, ...)
imap 返回一個迭代器,元素為 func(i1, i2, i3, ...),i1,i2 等分別來源于 iter, iter2。
>>> from itertools import imap >>> >>> imap(str, [1, 2, 3, 4])tee>>> >>> list(imap(str, [1, 2, 3, 4])) ["1", "2", "3", "4"] >>> >>> list(imap(pow, [2, 3, 10], [4, 2, 3])) [16, 9, 1000]
tee 的使用形式如下:
tee(iterable [,n])
tee 用于從 iterable 創建 n 個獨立的迭代器,以元組的形式返回,n 的默認值是 2。
>>> from itertools import tee >>> >>> tee("abcd") # n 默認為 2,創建兩個獨立的迭代器 (takewhile, ) >>> >>> iter1, iter2 = tee("abcde") >>> list(iter1) ["a", "b", "c", "d", "e"] >>> list(iter2) ["a", "b", "c", "d", "e"] >>> >>> tee("abc", 3) # 創建三個獨立的迭代器 ( , , )
takewhile 的使用形式如下:
takewhile(predicate, iterable)
其中,predicate 是函數,iterable 是可迭代對象。對于 iterable 中的元素,如果 predicate(item) 為 true,則保留該元素,只要 predicate(item) 為 false,則立即停止迭代。
>>> from itertools import takewhile >>> >>> list(takewhile(lambda x: x < 5, [1, 3, 6, 2, 1])) [1, 3] >>> list(takewhile(lambda x: x > 3, [2, 1, 6, 5, 4])) []izip
izip 用于將多個可迭代對象對應位置的元素作為一個元組,將所有元組『組成』一個迭代器,并返回。它的使用形式如下:
izip(iter1, iter2, ..., iterN)
如果某個可迭代對象不再生成值,則迭代停止。
>>> from itertools import izip >>> >>> for item in izip("ABCD", "xy"): ... print item ... ("A", "x") ("B", "y") >>> for item in izip([1, 2, 3], ["a", "b", "c", "d", "e"]): ... print item ... (1, "a") (2, "b") (3, "c")izip_longest
izip_longest 跟 izip 類似,但迭代過程會持續到所有可迭代對象的元素都被迭代完。它的形式如下:
izip_longest(iter1, iter2, ..., iterN, [fillvalue=None])
如果有指定 fillvalue,則會用其填充缺失的值,否則為 None。
>>> from itertools import izip_longest >>> >>> for item in izip_longest("ABCD", "xy"): ... print item ... ("A", "x") ("B", "y") ("C", None) ("D", None) >>> >>> for item in izip_longest("ABCD", "xy", fillvalue="-"): ... print item ... ("A", "x") ("B", "y") ("C", "-") ("D", "-")組合生成器
itertools 模塊還提供了多個組合生成器函數,用于求序列的排列、組合等:
product
permutations
combinations
combinations_with_replacement
productproduct 用于求多個可迭代對象的笛卡爾積,它跟嵌套的 for 循環等價。它的一般使用形式如下:
product(iter1, iter2, ... iterN, [repeat=1])
其中,repeat 是一個關鍵字參數,用于指定重復生成序列的次數,
>>> from itertools import product >>> >>> for item in product("ABCD", "xy"): ... print item ... ("A", "x") ("A", "y") ("B", "x") ("B", "y") ("C", "x") ("C", "y") ("D", "x") ("D", "y") >>> >>> list(product("ab", range(3))) [("a", 0), ("a", 1), ("a", 2), ("b", 0), ("b", 1), ("b", 2)] >>> >>> list(product((0,1), (0,1), (0,1))) [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)] >>> >>> list(product("ABC", repeat=2)) [("A", "A"), ("A", "B"), ("A", "C"), ("B", "A"), ("B", "B"), ("B", "C"), ("C", "A"), ("C", "B"), ("C", "C")] >>>permutations
permutations 用于生成一個排列,它的一般使用形式如下:
permutations(iterable[, r])
其中,r 指定生成排列的元素的長度,如果不指定,則默認為可迭代對象的元素長度。
>>> from itertools import permutations >>> >>> permutations("ABC", 2)combinations>>> >>> list(permutations("ABC", 2)) [("A", "B"), ("A", "C"), ("B", "A"), ("B", "C"), ("C", "A"), ("C", "B")] >>> >>> list(permutations("ABC")) [("A", "B", "C"), ("A", "C", "B"), ("B", "A", "C"), ("B", "C", "A"), ("C", "A", "B"), ("C", "B", "A")] >>>
combinations 用于求序列的組合,它的使用形式如下:
combinations(iterable, r)
其中,r 指定生成組合的元素的長度。
>>> from itertools import combinations >>> >>> list(combinations("ABC", 2)) [("A", "B"), ("A", "C"), ("B", "C")]combinations_with_replacement
combinations_with_replacement 和 combinations 類似,但它生成的組合包含自身元素。
>>> from itertools import combinations_with_replacement >>> >>> list(combinations_with_replacement("ABC", 2)) [("A", "A"), ("A", "B"), ("A", "C"), ("B", "B"), ("B", "C"), ("C", "C")]小結
itertools 模塊提供了很多用于產生多種類型迭代器的函數,它們的返回值不是 list,而是迭代器。
參考鏈接本文由 funhacks 發表于個人博客,采用 Creative Commons BY-NC-ND 4.0(自由轉載-保持署名-非商用-禁止演繹)協議發布。
非商業轉載請注明作者及出處。商業轉載請聯系作者本人。
本文標題為: 高效的 itertools 模塊
本文鏈接為: http://funhacks.net/2017/02/1...
itertools — Functions creating iterators for efficient looping
itertools – Iterator functions for efficient looping - Python Module of the Week
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/38434.html
摘要:借鑒了中的某些迭代器的構造方法,并在中實現該模塊是通過實現,源代碼。 項目地址:https://git.io/pytips 0x01 介紹了迭代器的概念,即定義了 __iter__() 和 __next__() 方法的對象,或者通過 yield 簡化定義的可迭代對象,而在一些函數式編程語言(見 0x02 Python 中的函數式編程)中,類似的迭代器常被用于產生特定格式的列表(或序列)...
摘要:常規的使用來統計一段代碼運行時間的例子輸出結果總結其實是一門特別人性化的語言,但凡在工程中經常遇到的問題,處理起來比較棘手的模式基本都有對應的比較優雅的解決方案。 python的高級特性 名詞與翻譯對照表 generator 生成器 iterator 迭代器 collection 集合 pack/unpack 打包/解包 decorator 裝飾器 context manager ...
摘要:抓住了迭代器模式的本質,即是迭代,賦予了它極高的地位。輸出結果輸出結果小結迭代器模式幾乎是種設計模式中最常用的設計模式,本文主要介紹了是如何運用迭代器模式,并介紹了模塊生成迭代器的種方法,以及種生成迭代器的內置方法。 showImg(https://segmentfault.com/img/bVbmv7W?w=4272&h=2848); 在軟件開發領域中,人們經常會用到這一個概念——設...
閱讀 3452·2023-04-26 01:45
閱讀 2227·2021-11-23 09:51
閱讀 3641·2021-10-18 13:29
閱讀 3437·2021-09-07 10:12
閱讀 702·2021-08-27 16:24
閱讀 1773·2019-08-30 15:44
閱讀 2198·2019-08-30 15:43
閱讀 2953·2019-08-30 13:11