itertools

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)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容