Модуль itertools

Введение

Примеры

  • 2

    Группировка элементов из повторяемого объекта с помощью функции

    Начните с итерации, которую нужно сгруппировать

     lst = [("a", 5, 6), ("b", 2, 4), ("a", 2, 5), ("c", 2, 6)]
    
     

    Генерация сгруппированного генератора, группировка по второму элементу в каждом кортеже:

     def testGroupBy(lst):
        groups = itertools.groupby(lst, key=lambda x: x[1])
        for key, group in groups:
            print(key, list(group))
    
    testGroupBy(lst)
    
    # 5 [('a', 5, 6)]
    # 2 [('b', 2, 4), ('a', 2, 5), ('c', 2, 6)]
    
     

    Только группы последовательных элементов сгруппированы. Возможно, вам придется отсортировать по одному и тому же ключу перед вызовом groupby. Например, (последний элемент изменен)

     lst = [("a", 5, 6), ("b", 2, 4), ("a", 2, 5), ("c", 5, 6)]
    testGroupBy(lst)
    
    # 5 [('a', 5, 6)]
    # 2 [('b', 2, 4), ('a', 2, 5)]
    # 5 [('c', 5, 6)]
    
     

    Группа, возвращаемая groupby, является итератором, который будет недействительным до следующей итерации. Например, следующее не будет работать, если вы хотите, чтобы группы сортировались по ключу. Группа 5 пуста ниже, потому что, когда группа 2 выбирается, она делает недействительным 5

     lst = [("a", 5, 6), ("b", 2, 4), ("a", 2, 5), ("c", 2, 6)]
    groups = itertools.groupby(lst, key=lambda x: x[1])
    for key, group in sorted(groups):
        print(key, list(group))
    
    # 2 [('c', 2, 6)]
    # 5 []
    
     

    Чтобы правильно выполнить сортировку, создайте список из итератора перед сортировкой

     groups = itertools.groupby(lst, key=lambda x: x[1])
    for key, group in sorted((key, list(group)) for key, group in groups):
        print(key, list(group))
    
    # 2 [('b', 2, 4), ('a', 2, 5), ('c', 2, 6)]
    # 5 [('a', 5, 6)] 
  • 2

    Возьми кусочек генератора

    Itertools "islice" позволяет нарезать генератор:

     results = fetch_paged_results()  # returns a generator
    limit = 20  # Only want the first 20 results
    for data in itertools.islice(results, limit):
        print(data)
    
     

    Обычно вы не можете нарезать генератор:

     def gen():
        n = 0
        while n < 20:
            n += 1
            yield n
    
    for part in gen()[:3]:
        print(part)
    
     

    Дам

     Traceback (most recent call last):
      File "gen.py", line 6, in <module>
        for part in gen()[:3]:
    TypeError: 'generator' object is not subscriptable
    
     

    Тем не менее, это работает:

     import itertools
    
    def gen():
        n = 0
        while n < 20:
            n += 1
            yield n
    
    for part in itertools.islice(gen(), 3):
        print(part)
    
     

    Обратите внимание , что как обычный ломтик, вы также можете использовать start , stop и step аргументы:

     itertools.islice(iterable, 1, 30, 3) 
  • 1

    itertools.product

    Эта функция позволяет перебирать декартово произведение списка итераций.

    Например,

     for x, y in itertools.product(xrange(10), xrange(10)):
        print x, y
    
     

    эквивалентно

     for x in xrange(10):
        for y in xrange(10):
            print x, y
    
     

    Как и все функции Python, которые принимают переменное число аргументов, мы можем передать список распаковке в itertools.product с помощью оператора *.

    Таким образом,

     its = [xrange(10)] * 2
    for x,y in itertools.product(*its):
        print x, y
    
     

    дает те же результаты, что и оба предыдущих примера.

     >>> from itertools import product
    >>> a=[1,2,3,4]
    >>> b=['a','b','c']
    >>> product(a,b)
    <itertools.product object at 0x0000000002712F78>
    >>> for i in product(a,b):
    ...     print i
    ...
    (1, 'a')
    (1, 'b')
    (1, 'c')
    (2, 'a')
    (2, 'b')
    (2, 'c')
    (3, 'a')
    (3, 'b')
    (3, 'c')
    (4, 'a')
    (4, 'b')
    (4, 'c') 
  • 1

    itertools.count

    Вступление:

    Эта простая функция генерирует бесконечные серии чисел. Например...

     for number in itertools.count():
        if number > 20:
            break
        print(number)
    
     

    Обратите внимание, что мы должны сломаться, или это печатает навсегда!

    Выход:

     0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
     

    Аргументы:

    count() - start step count() принимает два аргумента, start и step :

     for number in itertools.count(start=10, step=4):
        print(number)
        if number > 20:
            break
    
     

    Выход:

     10
    14
    18
    22 
  • 1

    itertools.takewhile

    itertools.takewhile позволяет принимать элементы из последовательности , пока условие не станет первым False .

     def is_even(x):
        return x % 2 == 0
    
    
    lst = [0, 2, 4, 12, 18, 13, 14, 22, 23, 44]
    result = list(itertools.takewhile(is_even, lst))
    
    print(result) 

    Эти выходы [0, 2, 4, 12, 18] .

    Отметим, что первое число , которое нарушает предикат (т.е. функция возвращает логическое значение) is_even есть, 13 . После того, как takewhile встречает значение , которое производит False для данного предиката, он вспыхивает.

    Выход производства takewhile похож на выходе генерируется из кода ниже.

     def takewhile(predicate, iterable):
        for x in iterable:
            if predicate(x):
                yield x
            else:
                break 

    Примечание: конкатенация результатов , полученных takewhile и dropwhile производит оригинальную Iterable.

    result = list(itertools.takewhile(is_even, lst)) + list(itertools.dropwhile(is_even, lst))

  • 3

    itertools.dropwhile

    itertools.dropwhile позволяет принимать элементы из последовательности после того, как условие первого становится False .

     def is_even(x):
        return x % 2 == 0
    
    
    lst = [0, 2, 4, 12, 18, 13, 14, 22, 23, 44]
    result = list(itertools.dropwhile(is_even, lst))
    
    print(result) 

    Эти выходы [13, 14, 22, 23, 44] .

    ( В этом примере такой же , как пример для takewhile , но с использованием dropwhile .)

    Отметим, что первое число , которое нарушает предикат (т.е. функция возвращает логическое значение) is_even есть, 13 . Все элементы до этого отбрасываются.

    Выход производства dropwhile похож на выходе генерируется из кода ниже.

     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 и dropwhile производит оригинальную Iterable.

    result = list(itertools.takewhile(is_even, lst)) + list(itertools.dropwhile(is_even, lst))

  • 2

    Молнии двух итераторов, пока они не исчерпаны

    Подобно встроенной функции zip() , itertools.zip_longest будет продолжать итерации после окончания короче двух итерируемых.

     from itertools import zip_longest
    a = [i for i in range(5)] # Length is 5
    b = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] # Length is 7
    for i in zip_longest(a, b):
        x, y = i  # Note that zip longest returns the values as a tuple
        print(x, y)
    
     

    Необязательный fillvalue аргумент может быть передан ( по умолчанию '' ) , так как:

     for i in zip_longest(a, b, fillvalue='Hogwash!'):
        x, y = i  # Note that zip longest returns the values as a tuple
        print(x, y)
    
     

    В Python 2.6 и 2.7, эта функция называется itertools.izip_longest .

  • 3

    Метод комбинаций в модуле Itertools

    itertools.combinations возвращает генератор последовательности к -combination списка.

    Другими словами: он будет возвращать генератор кортежей всех возможных K-накрест комбинаций входного списка.

    Например:

    Если у вас есть список:

     a = [1,2,3,4,5]
    b = list(itertools.combinations(a, 2))
    print b
    
     

    Выход:

    [(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]

    Выше выход генератора преобразуется в список кортежей из всех возможных комбинаций пары -wise списка входных a

    Вы также можете найти все 3 комбинации:

     a = [1,2,3,4,5]
    b = list(itertools.combinations(a, 3))
    print b
    
     

    Выход:

     [(1, 2, 3), (1, 2, 4), (1, 2, 5), (1, 3, 4),
     (1, 3, 5), (1, 4, 5), (2, 3, 4), (2, 3, 5),
     (2, 4, 5), (3, 4, 5)] 
  • 0

    Объединение нескольких итераторов в цепочку

    Используйте itertools.chain , чтобы создать единый генератор , который позволит получить значения из нескольких генераторов в последовательности.

     from itertools import chain
    a = (x for x in ['1', '2', '3', '4'])
    b = (x for x in ['x', 'y', 'z'])
    ' '.join(chain(a, b))
    
     

    Результаты в:

     '1 2 3 4 x y z'
    
     

    В качестве альтернативного конструктора, вы можете использовать Метод класс chain.from_iterable , который принимает в качестве единственного параметра итератора из итерируемых. Чтобы получить тот же результат, что и выше:

     ' '.join(chain.from_iterable([a,b])
    
     

    В то время как chain может принимать произвольное число аргументов, chain.from_iterable это единственный путь к цепи бесконечного числа итерируемых.

  • 1

    itertools.repeat

    Повторите что-нибудь n раз:

     >>> import itertools
    >>> for i in itertools.repeat('over-and-over', 3):
    ...    print(i)
    over-and-over
    over-and-over
    over-and-over 
  • 1

    Получить накопленную сумму чисел в итерируемом

    `Накапливать` дает кумулятивную сумму (или произведение) чисел. >>> импортировать itertools как есть >>> оператор импорта >>> list (it.accumulate ([1,2,3,4,5])) [1, 3, 6, 10, 15] >>> list ( it.accumulate ([1,2,3,4,5], func = operator.mul)) [1, 2, 6, 24, 120]
  • 1

    Перебирать элементы в итераторе

    cycle представляет собой бесконечный итератор.

     >>> import itertools as it
    >>> it.cycle('ABCD')
    A B C D A B C D A B C D ...
    
     

    Поэтому при использовании этого параметра старайтесь не создавать бесконечный цикл. Пример:

     >>> # Iterate over each element in cycle for a fixed range
    >>> cycle_iterator = it.cycle('abc123')
    >>> [next(cycle_iterator) for i in range(0, 10)]
    ['a', 'b', 'c', '1', '2', '3', 'a', 'b', 'c', '1'] 
  • 1

    itertools.permutations

    itertools.permutations возвращает генератор с последовательными г длиной перестановками элементов в итерации.

     a = [1,2,3]
    list(itertools.permutations(a))
    # [(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
    
    list(itertools.permutations(a, 2))
    [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
    
     

    если список содержит повторяющиеся элементы, полученные в результате перестановки будут иметь повторяющиеся элементы, вы можете использовать a set , чтобы получить уникальные перестановки:

    a = [1,2,1]
    list(itertools.permutations(a))
    # [(1, 2, 1), (1, 1, 2), (2, 1, 1), (2, 1, 1), (1, 1, 2), (1, 2, 1)]
    
    set(itertools.permutations(a))
    # {(1, 1, 2), (1, 2, 1), (2, 1, 1)}

Синтаксис

Параметры

Примечания