Документация по Python

Модуль itertools

В: Документация по Python

Введение

Примеры

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

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

 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)] 

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

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) 

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') 

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 

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))

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))

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

Подобно встроенной функции 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 .

Метод комбинаций в модуле 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)] 

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

Используйте 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 это единственный путь к цепи бесконечного числа итерируемых.

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 

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

`Накапливать` дает кумулятивную сумму (или произведение) чисел. >>> импортировать 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]

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

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'] 

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)}

Синтаксис

Параметры

Примечания

Еще от кодкамп
Замечательно! Вы успешно подписались.
Добро пожаловать обратно! Вы успешно вошли
Вы успешно подписались на кодкамп.
Срок действия вашей ссылки истек.
Ура! Проверьте свою электронную почту на наличие волшебной ссылки для входа.
Успех! Ваша платежная информация обновлена.
Ваша платежная информация не была обновлена.