itertools模塊
迭代器(生成器)在Python中是一種很常用也很好用的數(shù)據(jù)結(jié)構(gòu),比起列表(list)來說,迭代器最大的優(yōu)勢就是延遲計算,按需使用,從而提高開發(fā)體驗和運行效率,以至于在Python 3中map,filter等操作返回的不再是列表而是迭代器。
itertools.count()
count()創(chuàng)建一個無限的迭代器,可以指定起始位置和步長,會不停打印出自然數(shù)序列,當然你可以break跳出循環(huán)。
>>> import itertools
>>> natuals = itertools.count(1, 2)
>>> for n in natuals:
... print(n)
...
1
3
5
...
itertools.cycle()
cycle()會把傳入的一個序列無限重復下去。
>>> import itertools
>>> cs = itertools.cycle('ABC') # 注意字符串也是序列的一種
>>> for c in cs:
... print(c)
...
'A'
'B'
'C'
'A'
'B'
'C'
...
itertools.repeat()
repeat()負責把一個元素無限重復下去,不過如果提供第二個參數(shù)就可以限定重復次數(shù)。
>>> ns = itertools.repeat('A', 3)
>>> for n in ns:
... print(n)
...
A
A
A
上述幾種迭代器稱為無限迭代器,只有在for迭代時才會無限地迭代下去,如果只是創(chuàng)建了一個迭代對象,它不會事先把無限個元素生成出來,事實上也不可能在內(nèi)存中創(chuàng)建無限多個元素。
無限迭代器雖然可以無限迭代下去,但是通常我們會通過takewhile()等函數(shù)根據(jù)條件判斷來截取出一個有限的序列:
>>> natuals = itertools.count(1)
>>> ns = itertools.takewhile(lambda x: x < 5, natuals)
>>> list(ns)
[1, 2, 3, 4]
dropwhile()與takewhile()相反:
>>> natuals = itertools.dropwhile(lambda x: x < 5, range(10))
>>> print(list(natuals))
[5, 6, 7, 8, 9]
itertools.chain()
chain()可以把一組迭代對象串聯(lián)起來,形成一個更大的迭代器:
>>> for c in itertools.chain('ABC', 'XYZ'):
... print(c)
'A' 'B' 'C' 'X' 'Y' 'Z'
itertools.groupby()
groupby()把迭代器中相鄰的重復元素挑出來放在一起:
>>> for key, group in itertools.groupby('AAABBBCCAAA'):
... print(key, list(group))
...
A ['A', 'A', 'A']
B ['B', 'B', 'B']
C ['C', 'C']
A ['A', 'A', 'A']
實際上挑選規(guī)則是通過函數(shù)完成的,只要作用于函數(shù)的兩個元素返回的值相等,這兩個元素就被認為是在一組的,而函數(shù)返回值作為組的key。如果我們要忽略大小寫分組,就可以讓元素'A'和'a'都返回相同的key:
>>> for key, group in itertools.groupby('AaaBBbcCAAa', lambda c: c.upper()):
... print(key, list(group))
...
A ['A', 'a', 'a']
B ['B', 'B', 'b']
C ['c', 'C']
A ['A', 'A', 'a']
>>> for key, group in itertools.groupby(range(10), lambda x: x < 5 or x > 8):
... print(key, list(group))
True [0, 1, 2, 3, 4]
False [5, 6, 7, 8]
True [9]
itertools.accumulate()
accumulate()將返回累計求和結(jié)果,或者傳入兩個參數(shù)的話,由傳入的函數(shù)累積計算的結(jié)果。默認設定為累加。
>>> list(itertools.accumulate(range(10)))
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
accumulate(可迭代對象[, 函數(shù)])
>>> import operator
>>> list(accumulate(range(1, 5), operator.mul))
[1, 2, 6, 24]
itertools.combinations()
求列表或生成器中指定數(shù)目的元素不重復的所有組合。
>>> natuals = itertools.combinations(range(4), 3)
>>> print(list(natuals))
[(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)]
itertools.combinations_with_replacement()
允許重復元素的組合。
>>> natuals = itertools.combinations_with_replacement('ABC', 2)
>>> print(list(natuals))
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')]
itertools.permutations()
產(chǎn)生指定數(shù)目的元素的所有排列(順序有關(guān)):
>>> natuals = itertools.permutations('abc', 3)
>>> print(list(natuals))
['a', 'b', 'c'], ['a', 'c', 'b'], ['b', 'a', 'c'], ['b', 'c', 'a'], ['c', 'a', 'b']['c', 'b', 'a']