ITERTOOLS是一個高效循環的迭代函數集合。正好在最近的應用的時候用的比較多,網上幾個比較詳細的介紹帖子要麼寫的抽象,要麼例子不夠簡潔。就大概整理了一下,搬運成分偏少。反正不重複造輪子是一個比較pythonic的原則,因此有空就分享一下。不過我的推薦有空仍是能夠看一下這些內建函數自己的實現源碼,都很是簡潔。python
以及,這東西遇到某些沒有限制的leetcode題目不就是秒殺嗎,更別說生產環境的不少小數據處理需求了。作碼農不偷懶那仍是人嗎。數組
itertools主要來分爲三類函數,分別爲無限迭代器、輸入序列迭代器、組合生成器,咱們下面開始具體講解。緩存
一、Itertools.count(start=0, step=1) 建立一個迭代對象,生成從start開始的連續整數,步長爲step。 若是省略了start則默認從0開始,步長默認爲1 若是超過了sys.maxint
,則會移除而且從-sys.maxint-1
開始計數。bash
例:
from itertools import *
for i in izip(count(2,6), ['a', 'b', 'c']):
print i
輸出爲:
(2, 'a')
(8, 'b')
(14, 'c')
複製代碼
二、Itertools.cycle(iterable) 建立一個迭代對象,對於輸入的iterable的元素反覆執行循環操做,內部生成iterable中的元素的一個副本,這個副本用來返回循環中的重複項。函數
例:
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')
複製代碼
三、Itertools.repeat(object[, times]) 建立一個迭代器,重複生成object,若是沒有設置times,則會無線生成對象。工具
例:
from itertools import *
for i in repeat('kivinsae', 5):
print I
輸出爲:
kivinsae
kivinsae
kivinsae
kivinsae
kivinsae
複製代碼
0、itertools.accumulate(*iterables) 這個函數簡單來講就是一個累加器,不停對列表或者迭代器進行累加操做(這裏指每項累加)。測試
例:
from itertools import *
x = itertools.accumulate(range(10))
print(list(x))
輸出爲:
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
複製代碼
一、itertools.chain(*iterables) 把多個迭代器做爲參數,可是隻會返回單個迭代器。產生全部參數迭代器的內容,卻好似來自於一個單一的序列。簡單了講就是鏈接多個【列表】或者【迭代器】。ui
例:
from itertools import *
for i in chain(['p','x','e'], ['scp', 'nmb', 'balenciaga']):
print I
輸出爲:
p
x
e
scp
nmb
balenciaga
複製代碼
二、itertools.compress(data,selectors) 具體來講compress提供了一個對於原始數據的篩選功能,具體條件能夠設置的很是複雜,因此下面只列出相關的定義代碼來解釋。不過簡單來理解,就是說按照真值表進行元素篩選而已。spa
實現過程:
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']
複製代碼
三、itertools.dropwhile(predicate,iterable) dropwhile做用是建立一個迭代器,只要是函數predicate(item)爲True,則丟掉iterable中的項,可是若是predicate返回的是False,則生成iterable中的項和全部的後續項。 具體來講就是,在條件爲False以後的第一次,就返回迭代器中剩餘的全部項。在這個函數表達式裏面iterable的值會按索引一個個做爲predicate的參數進行計算。 簡單來講其實就是按照真值函數丟棄掉列表和迭代器前面的元素。code
例:
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
複製代碼
四、itertools.groupby(iterable[,key]) 返回一個集合的迭代器,集合內是按照key進行分組後的值。 若是iterable在屢次連續的迭代中生成了同一項,則會定義一個組,若是對這個函數應用一個分類列表,那麼分組會定義這個列表中全部的惟一項,key是一個函數並應用於每一項。若是這個函數有返回值,則這個值會用於後續的項,而不是和該項自己進行比較。這個函數返回的迭代器生成元素(key,group),key是分組的鍵值,group是迭代器,從而生成組成這個組的全部項目。 具體來講實現過程和示例以下:
實現過程:
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']
複製代碼
五、itertools.ifilter(predicate,iterable) 本函數返回一個迭代器,相似於針對於列表的函數filter(),可是隻包括測試函數返回True時候的值。和dropwhile()做用不一樣。 函數建立一個迭代器,只生成predicate(iterable)爲True的項,簡單來講就是返回iterable中全部計算後爲True的項。若是是非True則進行以後的其餘操做。
例:
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
複製代碼
六、itertools.ifilterfalse(predicate,iterable) 本函數和上面的ifilter同樣,惟一的區別是隻有當predicate(iterable)爲False時候才進行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
複製代碼
七、itertools.islice(iterable,stop) 簡單來講這個函數,就是對於一個迭代對象iterable,設定一個特定的切片/選取/截取規則,而後最後輸出一個特定的新的迭代對象的過程。這個stop實際上表明一個三元數組,也就是start,stop,step。若是start省略,默認從索引0開始;若是step被省略,則默認步長爲1;stop不能被省略。本質就是一個切片工具。
例:
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
複製代碼
八、itertools.imap(function,*iterable) 本函數建立一個迭代器,做用函數爲function1,function2,function3…,對應的變量來自迭代器iterable1,iterable2,iterable3…。而後返回一個(f1,f2,f3…)形式的元組。只要其中一個迭代器再也不生成值,這個函數就會中止。因此要處理好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
複製代碼
九、itertools.starmap(function,iterable) 本函數建立一個函數,其中內調用的function(*item),item來自於iterable。只有當迭代對象iterable生成的項適合這個函數的調用形式的時候,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
複製代碼
十、itertools.tee(iterable[,n=2]) 這個函數會返回若干個基於某個原始輸入的獨立迭代器。相似於Linux系統上的tee指令。若是不特意制定n的話,函數會默認是2。tee括號裏面最好使用標準輸入,而不是原始迭代器。否則會在某些緩存過程當中出現異常。
例:
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
複製代碼
十一、itertools.takewhile(predicate,iterable) 這個函數和dropwhile恰好相反,只要predicate計算後爲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
複製代碼
十二、itertools.izip( *iterables) 這個函數返回一個合併多個迭代器,成爲一個元組的迭代對象。相似於內置函數zip,但返回的是迭代對象而非列表。 建立一個迭代對象,生成元組(i1,i2,i3…)分別來自於i1,i2,i3…,只要提供的某個迭代器不在生成值,函數就會馬上中止。
例:
from itertools import *
for i in izip([1, 2, 3], ['a', 'b', 'c']):
print I
輸出爲:
(1, 'a')
(2, 'b')
(3, 'c')
複製代碼
1三、itertools.izip_longest(*iterable[,fillvalue]) 本函數和izip雷同,可是區別在於不會中止,會把全部輸入的迭代對象所有耗盡爲止,對於參數不匹配的項,會用None代替。很是容易理解。
例:
from itertools import *
for i in izip_longest([1, 2, 3], ['a', 'b']):
print I
輸出爲:
(1, 'a')
(2, 'b')
(3, None)
複製代碼
一、itertools.product(*iterable[,repeat]) 這個工具就是產生多個列表或者迭代器的n維積。若是沒有特別指定repeat默認爲列表和迭代器的數量。
例:
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')
複製代碼
二、itertools.permutations(iterable[,r]) 這個函數做用其實就是產生指定數目repeat的元素的全部排列,且順序有關,可是遇到原列表或者迭代器有重複元素的現象的時候,也會對應的產生重複項。這個時候最好用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)
]
複製代碼
三、itertools.combinations(iterable,r) 這個函數用來生成指定數目r的元素不重複的全部組合。注意和permutation的區分,以及這個組合是無序的,只考慮元素自己的unique性。
例:
import itertools
x = itertools.combinations(range(4), 3)
print(list(x))
輸出爲:
[(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)]
複製代碼
四、itertools.combinations_with_replacement(iterable,r) 這個函數用來生成指定數目r的元素可重複的全部組合。然而這個函數依然要保證元素組合的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’) ] 複製代碼