itertools模塊提供的全部是處理迭代功能的函數(shù),它們的返回值不是list,而是迭代對(duì)象,只有用for循環(huán)迭代的時(shí)候才真正計(jì)算
[TOC]
無(wú)限迭代器
count
返回一個(gè)無(wú)限迭代器 可以知道初始值和步長(zhǎng),as:count(2.5, 0.5) -> 2.5 3.0 3.5 ...
demo
def count_demo():
""" count(start=0, step=1) --> count object
返回以start開(kāi)頭的均勻間隔step步長(zhǎng)的值
"""
for item in itertools.count(1):
if item > 10:
break
print(item)
實(shí)現(xiàn)類(lèi)似于
def count(firstval=0, step=1):
x = firstval
while 1:
yield x
x += step
cycle
把傳入的一個(gè)序列無(wú)限重復(fù)下去, as:cycle('ABCD') --> A B C D A B C D A B C D ...
chain_demo
def cycle_demo(its=["a", "b", "c", "d"]):
"""
保存迭代對(duì)象的每個(gè)元素的副本,無(wú)限的重復(fù)返回每個(gè)元素的副本
"""
for _index, item in enumerate(itertools.cycle(its)):
if _index > 10:
break
print("{}--{}".format(_index, item))
實(shí)現(xiàn)類(lèi)似于
def cycle(iterable):
saved = []
for element in iterable:
yield element
saved.append(element)
while saved:
for element in saved:
yield element
repeat
把傳入的一個(gè)元素重復(fù)n次, as:repeat(10, 3) --> 10 10 10
demo
def repeat_demo(its=["a", "b", "c", "d"]):
""" 負(fù)責(zé)把一個(gè)對(duì)象無(wú)限重復(fù)下去,不過(guò)如果提供第二個(gè)參數(shù)就可以限定重復(fù)次數(shù)
repeat(object [,times]) -> create an iterator which returns the object
for the specified number of times. If not specified, returns the object
endlessly.
"""
for _index, item in enumerate(itertools.repeat(its, 4)):
print("{}--{}".format(_index, item))
實(shí)現(xiàn)類(lèi)似于
def repeat(object, times=None):
if times is None:
while True:
yield object
else:
for i in range(times):
yield object
在最短輸入序列上終止的迭代器
accumulate
accumulate([1,2,3,4,5]) --> 1 3 6 10 15
accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120
demo
def accumulate_demo(its=range(1, 10)):
"""累計(jì)求和(默認(rèn))
accumulate(iterable[, func]) --> accumulate object
Return series of accumulated sums (or other binary function results).
"""
for _index, i in enumerate(itertools.accumulate(its), 1):
print("{}-->{}".format(_index, i))
print("\n-----\n"*2)
import operator
# 累計(jì)求積
for _index, i in enumerate(itertools.accumulate(its, operator.mul), 1):
print("{}-->{}".format(_index, i))
print("\n-----\n"*2)
# 求次冪
for _index, i in enumerate(itertools.accumulate(range(2, 5), operator.pow), 2):
print("{}-->{}".format(_index, i))
實(shí)現(xiàn)類(lèi)似于
def accumulate(iterable, func=operator.add):
it = iter(iterable)
try:
total = next(it)
except StopIteration:
return
yield total
for element in it:
total = func(total, element)
yield total
chain
把一組迭代對(duì)象串聯(lián)起來(lái),形成一個(gè)更大的迭代器
chain('ABC', 'DEF') --> A B C D E F
demo
def chain_demo():
"""把一組迭代對(duì)象串聯(lián)起來(lái),形成一個(gè)更大的迭代器
chain(*iterables) --> chain object
"""
for i in itertools.chain('ABCD', '1234', 'QIYUAN'):
print(i, end=' ')
實(shí)現(xiàn)類(lèi)似于
def chain(*iterables):
for it in iterables:
for element in it:
yield element
compress
按要求過(guò)濾可迭代對(duì)象
compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
demo
def compress_demo():
""" 返回?cái)?shù)據(jù)對(duì)象中對(duì)應(yīng)規(guī)則為T(mén)rue的元素(跟filter很像) 當(dāng)data/selectors之一用盡時(shí)停止
在用一個(gè)可迭代對(duì)象過(guò)濾另一個(gè)可迭代對(duì)象時(shí)十分有用
compress(data, selectors) --> iterator over selected data
Return data elements corresponding to true selector elements.
Forms a shorter iterator from selected data elements using the
selectors to choose the data elements.
"""
for _index, i in enumerate(itertools.compress(range(100), (True, True, True, False, False, True))):
print("{}-->{}".format(_index, i))
實(shí)現(xiàn)類(lèi)似于
def compress(data, selectors):
return (d for d, s in zip(data, selectors) if s)
dropwhile
從可迭代對(duì)象里找到第一個(gè)不滿足過(guò)濾條件的元素,并把它及其后的所有元素都迭代出來(lái)
dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
demo
def dropwhile_demo():
"""返回迭代器中條件第一次為false之后的所有元素
dropwhile(predicate, iterable) --> dropwhile object
Drop items from the iterable while predicate(item) is true.
Afterwards, return every element until the iterable is exhausted.
"""
for i in itertools.dropwhile(lambda x: 5 < x < 10, range(1, 20)):
print(i, end=" ")
print("\n-----\n"*2)
for i in itertools.dropwhile(lambda x: 5 < x < 10, range(6, 20)):
print(i, end=" ")
實(shí)現(xiàn)類(lèi)似于
def dropwhile(predicate, iterable):
iterable = iter(iterable)
for x in iterable:
if not predicate(x):
yield x
break
for x in iterable:
yield x
takewhile
迭代一個(gè)可迭代對(duì)象,直到遇到不滿足條件的元素
takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
demo
def takewhile_demo():
"""返回元素,直到遇到不滿足predicate的元素終止 跟dropwhile相反
takewhile(predicate, iterable) --> takewhile object
Return successive entries from an iterable as long as the
predicate evaluates to true for each entry.
"""
for i in itertools.takewhile(lambda e: e < 5, range(10)):
print(i, end='')
實(shí)現(xiàn)類(lèi)似于
def takewhile(predicate, iterable):
for x in iterable:
if predicate(x):
yield x
else:
break
filterfalse
顧名思義 迭代出 不滿足過(guò)濾條件的元素
filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
demo
def filterfalse_demo():
"""過(guò)濾所有不滿足條件的元素(與filter相反)
filterfalse(function or None, sequence) --> filterfalse object
Return those items of sequence for which function(item) is false.
If function is None, return the items that are false.
"""
for i in itertools.filterfalse(lambda x: x % 2 == 0, range(10)):
print(i, end=" ")
print("\n-----\n"*2)
for i in itertools.filterfalse(None, range(10)):
print(i)
實(shí)現(xiàn)類(lèi)似于
def filterfalse(predicate, iterable):
if predicate is None:
predicate = bool
for x in iterable:
if not predicate(x):
yield x
groupby
把迭代器中相鄰的重復(fù)元素挑出來(lái)放在一起,判斷是否重復(fù) 不一定是需要是一樣才算一致,也可以自己指定判斷方法
[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
demo
def groupby_demo(its='AaabBbcCAAa'):
"""按照分組函數(shù)的值對(duì)元素進(jìn)行相鄰分組(默認(rèn)分組函數(shù)為相等)
groupby(iterable[, keyfunc]) -> create an iterator which returns
(key, sub-iterator) grouped by each value of key(value).
"""
for key, group in itertools.groupby(its, lambda c: c.upper()):
print(key, list(group))
實(shí)現(xiàn)類(lèi)似于
class groupby:
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
try:
self.currvalue = next(self.it)
except StopIteration:
return
self.currkey = self.keyfunc(self.currvalue)
islice
迭代器實(shí)現(xiàn)的切片, 不支持負(fù)數(shù)操作
islice('ABCDEFG', 2) --> A B
islice('ABCDEFG', 2, 4) --> C D
islice('ABCDEFG', 2, None) --> C D E F G
islice('ABCDEFG', 0, None, 2) --> A C E G
def islice(iterable, *args):
s = slice(*args)
it = iter(range(s.start or 0, s.stop or sys.maxsize, s.step or 1))
try:
nexti = next(it)
except StopIteration:
return
for i, element in enumerate(iterable):
if i == nexti:
yield element
nexti = next(it)
starmap
類(lèi)似于map函數(shù)
starmap(pow,[(1,2), (3,4), (5,6)]) --> 1, 81, 15625
demo
def starmap_demo():
""" 假設(shè)iterable將返回一個(gè)元組流,并使用這些元組作為參數(shù)給function調(diào)用
starmap(function, sequence) --> starmap object
Return an iterator whose values are returned from the function evaluated
with an argument tuple taken from the given sequence.
"""
import os
its = [
('/bin', 'python', 'lib'),
('/bin', 'java'),
('/usr', 'bin', 'python3'),
]
for i in itertools.starmap(os.path.join, its):
print(i)
實(shí)現(xiàn)類(lèi)似于
def starmap(function, iterable):
for args in iterable:
yield function(*args)
tee
把一個(gè)迭代器分成n個(gè)迭代器(不是切割,n個(gè)迭代器一致)
demo
def tee_demo():
""" 生成n個(gè)iterable, 因?yàn)樯善髦荒艿槐椋绻卸啻问褂玫男枨笾荒芡ㄟ^(guò)此函數(shù)創(chuàng)建多個(gè)iterable
tee(iterable, n=2) --> tuple of n independent iterators
"""
for i in itertools.tee(range(10), 3):
print(list(i))
實(shí)現(xiàn)類(lèi)似于
def tee(iterable, n=2):
it = iter(iterable)
deques = [collections.deque() for i in range(n)]
def gen(mydeque):
while True:
if not mydeque: # when the local deque is empty
try:
newval = next(it) # fetch a new value and
except StopIteration:
return
for d in deques: # load it to all the deques
d.append(newval)
yield mydeque.popleft()
return tuple(gen(d) for d in deques)
zip_longest
類(lèi)似于 zip,不過(guò)這里是以長(zhǎng)的迭代結(jié)束為結(jié)束
itertools.zip_longest([1,2,3,4], [11,22]) --> (1, 11), (2, 22), (3, None), (4, None)]
itertools.zip_longest([1,2,3,4], [11,22],fillvalue='?') ---> (1, 11), (2, 22), (3, '?'), (4, '?')
class ZipExhausted(Exception):
pass
def zip_longest(*args, **kwds):
# zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
fillvalue = kwds.get('fillvalue')
counter = len(args) - 1
def sentinel():
nonlocal counter
if not counter:
raise ZipExhausted
counter -= 1
yield fillvalue
fillers = repeat(fillvalue)
iterators = [chain(it, sentinel(), fillers) for it in args]
try:
while iterators:
yield tuple(map(next, iterators))
except ZipExhausted:
pass
組合生成器
product
生成笛卡爾積
product(*iterables, repeat=1) --> product object
product('ab', range(3)) --> ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2)
product((0,1), repeat=3) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ...
實(shí)現(xiàn)
def product(*args, repeat=1):
# product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
# product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
pools = [tuple(pool) for pool in args] * repeat
result = [[]]
for pool in pools:
result = [x+[y] for x in result for y in pool]
for prod in result:
yield tuple(prod)
permutations 排列
返回可迭代中的元素的連續(xù)r長(zhǎng)度排列(全排列)
permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
permutations(range(3)) --> 012 021 102 120 201 210
demo
def permutations_demo(its='ABCD', repeat=2):
"""袋子里有l(wèi)en(iterable), 摸 r 次 ,不放回 有多少種可能
permutations(iterable[, r]) --> permutations object
Return successive r-length permutations of elements in the iterable.
"""
list1 = itertools.permutations(its, repeat)
print(list(list1))
實(shí)現(xiàn)
# 代碼未看懂
def permutations(iterable, r=None):
pool = tuple(iterable)
n = len(pool)
r = n if r is None else r
if r > n:
return
indices = list(range(n))
cycles = list(range(n, n-r, -1))
yield tuple(pool[i] for i in indices[:r])
while n:
for i in reversed(range(r)):
cycles[i] -= 1
if cycles[i] == 0:
indices[i:] = indices[i+1:] + indices[i:i+1]
cycles[i] = n - i
else:
j = cycles[i]
indices[i], indices[-j] = indices[-j], indices[i]
yield tuple(pool[i] for i in indices[:r])
break
else:
return
combinations 組合
從輸入可迭代返回r個(gè)元素的長(zhǎng)度子序列;但是以字典序打印并且內(nèi)容相同但順序不同也被視為一個(gè);一個(gè)元素只能出現(xiàn)一次
combinations('ABCD', 2) --> AB AC AD BC BD CD
combinations(range(4), 3) --> 012 013 023 123
demo
def combinations_demo(its='123456', repeat=2):
"""骰子有6面
combinations(iterable, r) --> combinations object
Return successive r-length combinations of elements in the iterable.
combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)
"""
list1 = itertools.combinations(its, 3)
print(list(list1))
實(shí)現(xiàn)
# 代碼未看懂
def combinations(iterable, r):
pool = tuple(iterable)
n = len(pool)
if r > n:
return
indices = list(range(r))
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(range(r)):
if indices[i] != i + n - r:
break
else:
return
indices[i] += 1
for j in range(i+1, r):
indices[j] = indices[j-1] + 1
yield tuple(pool[i] for i in indices)
combinations_with_replacement 組合
前兩點(diǎn)跟
itertools.combinations;可以出現(xiàn)自身
combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
demo
def combinations_with_replacement_demo(its='ABCD', repeat=2):
"""袋子里有l(wèi)en(iterable), 摸 r 次 ,摸完放回 有多少種可能
combinations_with_replacement(iterable, r) --> combinations_with_replacement object
Return successive r-length combinations of elements in the iterable
allowing individual elements to have successive repeats.
combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
"""
list1 = itertools.combinations_with_replacement(its, repeat)
print(list(list1))
實(shí)現(xiàn)
# 代碼未看懂
def combinations_with_replacement(iterable, r):
pool = tuple(iterable)
n = len(pool)
if not n and r:
return
indices = [0] * r
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(range(r)):
if indices[i] != n - 1:
break
else:
return
indices[i:] = [indices[i] + 1] * (r - i)
yield tuple(pool[i] for i in indices)