Python Language
Itertools-Modul
Suche…
Syntax
import itertools
Elemente aus einem iterierbaren Objekt mithilfe einer Funktion gruppieren
Beginnen Sie mit einer Iteration, die gruppiert werden muss
lst = [("a", 5, 6), ("b", 2, 4), ("a", 2, 5), ("c", 2, 6)]
Generieren Sie den gruppierten Generator nach dem zweiten Element in jedem Tupel:
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)]
Es werden nur Gruppen aufeinanderfolgender Elemente gruppiert. Möglicherweise müssen Sie nach demselben Schlüssel sortieren, bevor Sie groupby aufrufen. Beispiel: (Letztes Element wird geändert)
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)]
Die von groupby zurückgegebene Gruppe ist ein Iterator, der vor der nächsten Iteration ungültig ist. Das Folgende funktioniert beispielsweise nicht, wenn Sie die Gruppen nach Schlüssel sortieren möchten. Gruppe 5 ist unten leer. Wenn Gruppe 2 abgerufen wird, wird sie ungültig 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 []
Um die Sortierung korrekt durchzuführen, erstellen Sie vor dem Sortieren eine Liste im Iterator
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)]
Nehmen Sie ein Stück eines Generators
Mit Itertools "islice" können Sie einen Generator schneiden:
results = fetch_paged_results() # returns a generator
limit = 20 # Only want the first 20 results
for data in itertools.islice(results, limit):
print(data)
Normalerweise können Sie einen Generator nicht schneiden:
def gen():
n = 0
while n < 20:
n += 1
yield n
for part in gen()[:3]:
print(part)
Werde geben
Traceback (most recent call last):
File "gen.py", line 6, in <module>
for part in gen()[:3]:
TypeError: 'generator' object is not subscriptable
Dies funktioniert jedoch:
import itertools
def gen():
n = 0
while n < 20:
n += 1
yield n
for part in itertools.islice(gen(), 3):
print(part)
Beachten Sie, dass Sie wie ein normales Slice auch Argumente für start
, stop
und step
:
itertools.islice(iterable, 1, 30, 3)
itertools.product
Mit dieser Funktion können Sie das kartesische Produkt einer Liste von Iterablen durchlaufen.
Zum Beispiel,
for x, y in itertools.product(xrange(10), xrange(10)):
print x, y
ist äquivalent zu
for x in xrange(10):
for y in xrange(10):
print x, y
Wie alle Python-Funktionen, die eine variable Anzahl von Argumenten akzeptieren, können wir mit dem Operator * eine Liste an itertools.product zum Entpacken übergeben.
Somit,
its = [xrange(10)] * 2
for x,y in itertools.product(*its):
print x, y
erzeugt die gleichen Ergebnisse wie in den beiden vorherigen Beispielen.
>>> 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
Einführung:
Diese einfache Funktion erzeugt eine unendliche Anzahl von Zahlen. Zum Beispiel...
for number in itertools.count():
if number > 20:
break
print(number)
Beachten Sie, dass wir brechen müssen oder es für immer druckt!
Ausgabe:
0
1
2
3
4
5
6
7
8
9
10
Argumente:
count()
benötigt zwei Argumente, start
und step
:
for number in itertools.count(start=10, step=4):
print(number)
if number > 20:
break
Ausgabe:
10
14
18
22
itertools.takewhile
Mit itertools.takewhile können Sie Elemente aus einer Sequenz übernehmen, bis eine Bedingung zuerst 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)
Dies gibt [0, 2, 4, 12, 18]
.
Beachten Sie, dass die erste Zahl, die das Prädikat verletzt (dh die Funktion, die einen booleschen Wert is_even
, 13
. Sobald sich takewhile
trifft, takewhile
ein Wert auf einen False
Wert für das angegebene Prädikat trifft, bricht es aus.
Der Ausgang von erzeugten takewhile
ist ähnlich das Ausgangssignal von dem unten Code erzeugt.
def takewhile(predicate, iterable):
for x in iterable:
if predicate(x):
yield x
else:
break
Hinweis: Die Verkettung der Ergebnisse, die durch das takewhile
von takewhile
und dropwhile
des dropwhile
erzeugt werden, erzeugt das ursprüngliche iterierbare Ergebnis.
result = list(itertools.takewhile(is_even, lst)) + list(itertools.dropwhile(is_even, lst))
itertools
Mit itertools.drop können Sie Elemente aus einer Sequenz übernehmen, nachdem eine Bedingung zuerst 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)
Dies gibt [13, 14, 22, 23, 44]
.
( Dieses Beispiel ist das gleiche wie das Beispiel für takewhile
jedoch mit dropwhile
. )
Beachten Sie, dass die erste Zahl, die das Prädikat verletzt (dh die Funktion, die einen booleschen Wert is_even
, 13
. Alle Elemente davor werden verworfen.
Der Ausgang von erzeugten dropwhile
ist ähnlich das Ausgangssignal von dem unten Code erzeugt.
def dropwhile(predicate, iterable):
iterable = iter(iterable)
for x in iterable:
if not predicate(x):
yield x
break
for x in iterable:
yield x
Die Verkettung der Ergebnisse, die durch takewhile
und dropwhile
erzeugt werden, erzeugt das ursprüngliche iterable.
result = list(itertools.takewhile(is_even, lst)) + list(itertools.dropwhile(is_even, lst))
Zippen Sie zwei Iteratoren, bis beide erschöpft sind
Ähnlich wie bei der eingebauten Funktion zip()
wird itertools.zip_longest
auch nach dem Ende der kürzeren von zwei Iterationen 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)
Ein optionales fillvalue
Argument kann wie fillvalue
übergeben werden ( 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)
In Python 2.6 und 2.7 heißt diese Funktion itertools.izip_longest
.
Kombinationsmethode im Itertools-Modul
itertools.combinations
einen Generator der k- Kombinationsfolge einer Liste.
Mit anderen Worten: Es wird ein Generator von Tupeln aller möglichen k-weisen Kombinationen der Eingabeliste zurückgegeben.
Zum Beispiel:
Wenn Sie eine Liste haben:
a = [1,2,3,4,5]
b = list(itertools.combinations(a, 2))
print b
Ausgabe:
[(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
Die obige Ausgabe ist ein Generator, der in eine Liste von Tupeln aller möglichen paarweisen Kombinationen der Eingabeliste a
Sie können auch alle 3 Kombinationen finden:
a = [1,2,3,4,5]
b = list(itertools.combinations(a, 3))
print b
Ausgabe:
[(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)]
Mehrere Iteratoren miteinander verketten
Verwenden Sie itertools.chain
, um einen einzelnen Generator zu erstellen, der die Werte von mehreren Generatoren nacheinander liefert.
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))
Ergebnisse in:
'1 2 3 4 x y z'
Als alternativen Konstruktor können Sie die Klassenmethode chain.from_iterable
die als einzigen Parameter eine iterierbare Option chain.from_iterable
iterierbare Werte verwendet. Um das gleiche Ergebnis wie oben zu erhalten:
' '.join(chain.from_iterable([a,b])
Während chain
eine beliebige Anzahl von Argumenten chain.from_iterable
ist chain.from_iterable
die einzige Möglichkeit, eine unendliche Anzahl von chain.from_iterable
.
itertools.repeat
N mal wiederholen:
>>> import itertools
>>> for i in itertools.repeat('over-and-over', 3):
... print(i)
over-and-over
over-and-over
over-and-over
Erhalten Sie eine kumulierte Summe von Zahlen in einem iterierbaren Element
accumulate
ergibt eine kumulative Summe (oder Produkt) von Zahlen
>>> import itertools as it
>>> import operator
>>> 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]
Durchlaufen Sie Elemente in einem Iterator
cycle
ist ein unendlicher Iterator.
>>> import itertools as it
>>> it.cycle('ABCD')
A B C D A B C D A B C D ...
Achten Sie daher darauf, Grenzen zu verwenden, um eine Endlosschleife zu vermeiden. Beispiel:
>>> # 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
gibt einen Generator mit aufeinanderfolgenden Permutationen der Elemente in der iterierbaren Länge zurück.
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)]
Wenn die Liste a
doppelte Elemente enthält, haben die resultierenden Permutationen doppelte Elemente. Sie können set
, um eindeutige Permutationen zu erhalten:
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)}