Zoeken…


Syntaxis

  • import itertools

Items van een iterabel object groeperen met een functie

Begin met een iterabele die moet worden gegroepeerd

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

Genereer de gegroepeerde generator, gegroepeerd op het tweede element in elke tuple:

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

Alleen groepen opeenvolgende elementen worden gegroepeerd. Mogelijk moet u op dezelfde toets sorteren voordat u groupby oproept. Bijvoorbeeld: (laatste element is gewijzigd)

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

De groep die wordt geretourneerd door groupby is een iterator die ongeldig is vóór de volgende iteratie. Het volgende werkt bijvoorbeeld niet als u wilt dat de groepen op sleutel worden gesorteerd. Groep 5 is hieronder leeg, omdat wanneer groep 2 wordt opgehaald 5 ongeldig wordt

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

Om correct te sorteren, maak een lijst van de iterator voordat u sorteert

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

Neem een plakje generator

Met Itertools "islice" kunt u een generator snijden:

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

Normaal gesproken kun je een generator niet segmenteren:

def gen():
    n = 0
    while n < 20:
        n += 1
        yield n

for part in gen()[:3]:
    print(part)

Zullen geven

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

Dit werkt echter:

import itertools

def gen():
    n = 0
    while n < 20:
        n += 1
        yield n

for part in itertools.islice(gen(), 3):
    print(part)

Merk op dat als een normale snee, dan kunt u ook gebruik maken van start , stop en step argumenten:

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

itertools.product

Met deze functie kunt u het Cartesiaanse product van een lijst met iterables herhalen.

Bijvoorbeeld,

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

is gelijk aan

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

Zoals alle python-functies die een variabel aantal argumenten accepteren, kunnen we een lijst doorgeven aan itertools.product voor uitpakken, met de operator *.

Dus,

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

produceert dezelfde resultaten als beide voorgaande voorbeelden.

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

Invoering:

Deze eenvoudige functie genereert een oneindige reeks getallen. Bijvoorbeeld...

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

Merk op dat we moeten breken, anders wordt het voor altijd afgedrukt!

Output:

0
1
2
3
4
5
6
7
8
9
10

argumenten:

count() neemt twee argumenten, start en step :

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

Output:

10
14
18
22

itertools.takewhile

itertools.takewhile stelt u in staat om items uit een reeks te nemen totdat een voorwaarde eerst 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)
  

Dit voert [0, 2, 4, 12, 18] .

Merk op dat het eerste getal dat het predicaat schendt (dwz: de functie die een Booleaanse waarde retourneert) is_even is, 13 . Zodra takewhile een waarde tegenkomt die False produceert voor het gegeven predicaat, breekt het uit.

De output geproduceerd door takewhile is vergelijkbaar met de output gegenereerd door de onderstaande code.

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

Opmerking: De samenvoeging van resultaten die zijn geproduceerd door takewhile en dropwhile levert de oorspronkelijke iterabele op.

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

itertools.dropwhile

Met itertools.dropwhile kunt u items uit een reeks nemen nadat een voorwaarde eerst 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)
  

Dit voert [13, 14, 22, 23, 44] .

( Dit voorbeeld is hetzelfde als het voorbeeld voor takewhile maar met dropwhile . )

Merk op dat het eerste getal dat het predicaat schendt (dwz: de functie die een Booleaanse waarde retourneert) is_even is, 13 . Alle elementen daarvoor worden weggegooid.

De output geproduceerd door dropwhile is vergelijkbaar met de output gegenereerd door de onderstaande code.

def dropwhile(predicate, iterable):
    iterable = iter(iterable)
    for x in iterable:
        if not predicate(x):
            yield x
            break
    for x in iterable:
        yield x

De samenvoeging van resultaten geproduceerd door takewhile en dropwhile produceert de originele iterabele.

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

Ritsen van twee iterators totdat ze allebei uitgeput zijn

Net als bij de ingebouwde functie zip() , zal itertools.zip_longest doorgaan met itereren voorbij het einde van de kortere van twee iterables.

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)

Een optioneel fillvalue argument kan als volgt worden doorgegeven (standaard ingesteld op '' ):

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 en 2.7 wordt deze functie itertools.izip_longest .

Combinatiemethode in Itertools Module

itertools.combinations retourneert een generator van de k -combinatiesequentie van een lijst.

Met andere woorden: het retourneert een generator van tupels van alle mogelijke k-gewijs combinaties van de invoerlijst.

Bijvoorbeeld:

Als u een lijst hebt:

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

Output:

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

De bovenstaande uitvoer is een generator omgezet in een lijst met tupels van alle mogelijke paren- combinaties van de invoerlijst a

Je kunt ook alle 3-combinaties vinden:

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

Output:

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

Meerdere iterators aan elkaar koppelen

Gebruik itertools.chain om een enkele generator te maken die de waarden van verschillende generators achter elkaar oplevert.

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

Resulteert in:

'1 2 3 4 x y z'

Als alternatieve constructor kunt u de classmethod chain.from_iterable die als zijn enige parameter een iterabele iterables neemt. Om hetzelfde resultaat te krijgen als hierboven:

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

Hoewel chain een willekeurig aantal argumenten kan chain.from_iterable is chain.from_iterable de enige manier om een oneindig aantal iterables te koppelen.

itertools.repeat

Herhaal iets n keer:

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

Krijg een verzamelde som van getallen in een iterabel

Python 3.x 3.2

accumulate levert een cumulatieve som (of product) van getallen op.

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

Doorloop elementen in een iterator

cycle is een oneindige iterator.

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

Zorg er daarom voor dat u grenzen geeft wanneer u dit gebruikt om een oneindige lus te voorkomen. Voorbeeld:

>>> # 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 retourneert een generator met opeenvolgende r-lengte permutaties van elementen in het iterabele.

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

als de lijst a dubbele elementen heeft, zullen de resulterende permutaties dubbele elementen hebben, u kunt set gebruiken om unieke permutaties te krijgen:

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


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow