Vad är Python Itertools-funktioner?

Enligt Pythons dokumentation är Itertools en Python-modul som tillhandahåller en uppsättning snabba och minneseffektiva verktyg för att arbeta med Python-iteratorer. Dessa verktyg kan användas var för sig eller i kombination, och de gör det möjligt att kortfattat och effektivt skapa och arbeta med iteratorer på ett snabbt och minneseffektivt sätt.

Itertools-modulen innehåller funktioner som gör det lättare att arbeta med iteratorer, särskilt vid hantering av stora uppsättningar data. Itertools-funktioner kan fungera på befintliga iteratorer för att skapa ännu mer komplexa Python-iteratorer.

Dessutom kan Itertools hjälpa utvecklare att minska fel när de arbetar med iteratorer och skriva renare, läsbar och underhållbar kod.

Baserat på den funktionalitet som iteratorerna i Itertools-modulen tillhandahåller, kan de klassificeras i följande typer:

#1. Oändliga iteratorer

Det här är iteratorer som låter dig arbeta med oändliga sekvenser och köra en loop i oändlighet om det inte finns något villkor för att bryta ut ur loopen. Sådana iteratorer är användbara när man simulerar oändliga loopar eller genererar en obunden sekvens. Itertools har tre oändliga iteratorer, som inkluderar count(), cycle() och repeat().

#2. Kombinatoriska iteratorer

Kombinatoriska iteratorer omfattar funktioner som kan användas för att arbeta på kartesiska produkter och utföra kombinationer och permutationer av element som finns i en iterabel. Dessa är de viktigaste funktionerna när man försöker hitta alla möjliga sätt att ordna eller kombinera element i en iterabel. Itertools har fyra kombinatoriska iteratorer. Dessa är produkt(), permutationer(), kombinationer() och kombinationer_med_ersättning().

#3. Iteratorer som avslutas på den kortaste ingångssekvensen

Dessa är avslutande iteratorer som används på ändliga sekvenser och genererar en utdata baserat på vilken typ av funktion som används. Exempel på dessa avslutande iteratorer inkluderar: accumulate(), chain(), chain.from_iterable(), compress(), dropwhile(), filterfalse(), groupby(), islice(), pairwise(), starmap(), takewhile (), tee() och zip_longest().

Låt oss titta på hur olika Itertools-funktioner fungerar beroende på deras typ:

Oändliga iteratorer

De tre oändliga iteratorerna inkluderar:

#1. räkna()

Funktionen räkna (start, steg) genererar en oändlig sekvens av tal som börjar från startvärdet. Funktionen tar två valfria argument: start och steg. Argumentet start anger var talföljden ska börja. Som standard börjar den vid 0 om ett startvärde inte anges. steg ställer in skillnaden mellan varje på varandra följande nummer. Standardstegvärdet är 1.

import itertools
# count starting at 4, making steps of 2  
for i in itertools.count(4, 2):
    # condition to end the loop avoiding infinite looping
    if i == 14:
        break
    else:
        print(i) # output - 4, 6, 8, 10, 12

Produktion

4
6
8
10
12

#2. cykel()

cycle(iterable)-funktionen tar en iterabel som ett argument och cyklar sedan genom iterablen och tillåter åtkomst till objekt i iterablen i den ordning de visas.

Till exempel om vi passerar in [“red”, “green”, “yellow”] into cycle(), i den första cykeln har vi tillgång till ”red”; i den andra cykeln har vi tillgång till ”grönt”, sedan ”gult”. I den fjärde cykeln, eftersom alla element har uttömts i iterabeln, börjar vi om på ”rött” och fortsätter sedan i det oändliga.

När du anropar cycle() lagrar du dess resultat i en variabel för att skapa en iterator som bibehåller sitt tillstånd. Detta säkerställer att cykeln inte startar om varje gång, vilket ger dig tillgång till endast det första elementet.

import itertools

colors = ["red", "green", "yellow"]
# pass in colors into cycle()
color_cycle = itertools.cycle(colors)
print(color_cycle)

# range used to stop the infinite loop once we've printed 7 times
# next() used to return the next item from the iterator
for i in range(7):
    print(next(color_cycle))

Produktion:

red
green
yellow
red
green
yellow
red

#3. upprepa()

repeat(elem,n) tar två argument, ett element att upprepa (elem), och antalet gånger du vill upprepa elementet(n). Elementet du vill upprepa kan vara ett enstaka värde eller ett iterabelt. Om du inte passerar in, n, kommer elementet att upprepas i oändlighet.

import itertools
   
for i in itertools.repeat(10, 3):
    print(i)

Produktion:

10 
10
10

Kombinatoriska iteratorer

De kombinatoriska iteratorerna inkluderar:

#1. produkt()

product() är en funktion som används för att beräkna den kartesiska produkten av den iterabel som skickas till den. Om vi ​​har två iterabler eller mängder, till exempel, x = {7,8} och y = {1,2,3}, kommer den kartesiska produkten av x och y att innehålla alla möjliga kombinationer av element från x och y, där första elementet är från x och det andra från y. Den kartesiska produkten av x och y i detta fall är [(7, 1), (7, 2), (7, 3), (8, 1), (8, 2), (8, 3)].

product() tar en valfri parameter som kallas repeat som används för att beräkna den kartesiska produkten av en iterabel med sig själv. repeat anger antalet repetitioner för varje element från indata iterables vid beräkning av den kartesiska produkten.

Att till exempel anropa product(’ABCD’, repeat=2) ger kombinationer som (’A’, ’A’), (’A’, ’B’), (’A’, ’C’) och så på. Om upprepning sattes till 3, skulle funktionen ge kombinationer som (’A’, ’A’, ’A’), (’A’, ’A’, ’B’), (’A’, ’A’ , ’C’), (’A’, ’A’, ’D’) och så vidare.

from itertools import product
# product() with the optional repeat argument
print("product() with the optional repeat argument ")
print(list(product('ABC', repeat = 2)))

# product with no repeat
print("product() WITHOUT an optional repeat argument")
print(list(product([7,8], [1,2,3])))

Produktion

product() with the optional repeat argument 
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'B'), ('B', 'C'), ('C', 'A'), ('C', 'B'), ('C', 'C')]
product() WITHOUT an optional repeat argument
[(7, 1), (7, 2), (7, 3), (8, 1), (8, 2), (8, 3)]

#2. permutationer()

permutations(iterable, group_size) returnerar alla möjliga permutationer av den iterable som skickas in i den. En permutation representerar antalet sätt som element i en uppsättning kan ordnas på. permutations() tar ett valfritt argument group_size. Om group_size inte anges, kommer de genererade permutationerna att ha samma storlek som längden på den iterable som skickas till funktionen

import itertools
numbers = [1, 2, 3]
sized_permutations = list(itertools.permutations(numbers,2))
unsized_permuatations = list(itertools.permutations(numbers))

print("Permutations with a size of 2")
print(sized_permutations)
print("Permutations with NO size argument")
print(unsized_permuatations)

Produktion

Permutations with a group size of 2
[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
Permutations with NO size argument
[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]

#3. kombinationer()

kombinationer(iterbar, storlek) returnerar alla möjliga kombinationer av en iterabel av en given längd från elementen i iterabeln som skickats till funktionen. Storleksargumentet anger storleken på varje kombination.

Resultaten är ordnade. Kombination skiljer sig något från permutationer. Med permutation spelar ordningen roll, men med kombination spelar ordningen ingen roll. Till exempel i [A, B, C] det finns 6 permutationer: AB, AC, BA, BC, CA, CB men bara 3 kombinationer AB, AC, BC.

import itertools
numbers = [1, 2, 3,4]
size2_combination = list(itertools.combinations(numbers,2))
size3_combination = list(itertools.combinations(numbers, 3))

print("Combinations with a size of 2")
print(size2_combination)
print("Combinations with a size of 3")
print(size3_combination)

Produktion:

Combinations with a size of 2
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
Combinations with a size of 3
[(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]

#4. kombinationer_med_ersättning()

combines_with_replacement(iterable, size) genererar alla möjliga kombinationer av en iterabel av en given längd från den iterable som skickas in i funktionen och tillåter upprepade element i utdatakombinationerna. Storleken avgör storleken på de kombinationer som genereras.

Denna funktion skiljer sig från kombinationer() genom att den ger kombinationer där ett element kan upprepas mer än en gång. Till exempel kan du få en kombination som (1,1) vilket du inte kan med kombination().

import itertools
numbers = [1, 2, 3,4]

size2_combination = list(itertools.combinations_with_replacement(numbers,2))
print("Combinations_with_replacement => size 2")
print(size2_combination)

Produktion

Combinations_with_replacement => size 2
[(1, 1), (1, 2), (1, 3), (1, 4), (2, 2), (2, 3), (2, 4), (3, 3), (3, 4), (4, 4)]

Avslutande iteratorer

Detta inkluderar iteratorer som:

#1. ackumulera()

accumulate(iterable, function) tar ett iterbart och ett andra valfritt argument som är en funktion. Den returnerar sedan det ackumulerade resultatet av att tillämpa funktionen i varje iteration på element på den iterbara. Om ingen funktion godkänns görs tillägget och de ackumulerade resultaten returneras.

import itertools
import operator
numbers = [1, 2, 3, 4, 5]

# Accumulate the sum of numbers
accumulated_val = itertools.accumulate(numbers)
accumulated_mul = itertools.accumulate(numbers, operator.mul)
print("Accumulate with no function")
print(list(accumulated_val))
print("Accumulate with multiplication")
print(list(accumulated_mul))

Produktion:

Accumulate with no function
[1, 3, 6, 10, 15]
Accumulate with multiplication
[1, 2, 6, 24, 120]

#2. kedja()

chain(iterable_1, iterable_2, …) tar flera iterables och kopplar ihop dem och producerar en enda iterable innehållande värden från de iterables som skickas till chain()-funktionen

import itertools

letters = ['A', 'B', 'C', 'D']
numbers = [1, 2, 3]
colors = ['red', 'green', 'yellow']

# Chain letters and numbers together
chained_iterable = list(itertools.chain(letters, numbers, colors))
print(chained_iterable)

Produktion:

['A', 'B', 'C', 'D', 1, 2, 3, 'red', 'green', 'yellow']

#3. chain.from_iterable()

chain.from_iterable(iterable) denna funktion liknar chain(). Den skiljer sig dock från kedjan genom att den bara tar en enda iterabel innehållande sub-iterables och kedjer dem samman.

import itertools

letters = ['A', 'B', 'C', 'D']
numbers = [1, 2, 3]
colors = ['red', 'green', 'yellow']

iterable = ['hello',colors, letters, numbers]
chain = list(itertools.chain.from_iterable(iterable))
print(chain)

Produktion:

['h', 'e', 'l', 'l', 'o', 'red', 'green', 'yellow', 'A', 'B', 'C', 'D', 1, 2, 3]

#4. komprimera()

compress(data, selectors) tar in två argument, data som är en iterabel och selectors som är en iterabel som innehåller booleska värden true och false. 1, 0 kan också användas som alternativ till de booleska värdena sant och falskt. compress() filtrerar sedan överförda data med hjälp av motsvarande element som skickas i väljaren.

Värden i data som motsvarar värdet sant eller 1 i väljaren väljs, medan resten som motsvarar falskt eller 0 ignoreras. Om du skickar färre booleaner i väljare än antalet objekt i data ignoreras alla element utöver de godkända booleanerna i väljare

import itertools

# data has 10 items
data = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
# passing in 9 selector items
selectors = [True, False, 1, False, 0, 1, True, False, 1]

# Select elements from data based on selectors
filtered_data = list(itertools.compress(data, selectors))
print(filtered_data)

Produktion:

['A', 'C', 'F', 'G', 'I']

#5. dropwhile()

dropwhile(funktion, sekvens) tar in en funktion med villkoret som returnerar sant eller falskt och en sekvens av värden. Den tappar sedan alla värden tills det godkända villkoret returnerar False. När villkoret returnerar falskt, inkluderas resten av elementen i dess resultat oavsett om de skulle returnera True eller False.

import itertools

numbers = [1, 2, 3, 4, 5, 1, 6, 7, 2, 1, 8, 9, 0, 7]

# Drop elements until the passed condition is False
filtered_numbers = list(itertools.dropwhile(lambda x: x < 5, numbers))
print(filtered_numbers)

Produktion:

[5, 1, 6, 7, 2, 1, 8, 9, 0, 7]

#6. filterfalse()

filterfalse(funktion, sekvens) tar in en funktion, med ett villkor som utvärderas till sant eller falskt och en sekvens. Den returnerar sedan värden från sekvensen som inte uppfyller villkoret i funktionen.

import itertools

numbers = [1, 2, 3, 4, 2, 3 5, 6, 5, 8, 1, 2, 3, 6, 2, 7, 4, 3]

# Filter elements for which condition is False
filtered_numbers = list(itertools.filterfalse(lambda x: x < 4, numbers))
print(filtered_numbers)

Produktion:

[4, 5, 6, 5, 8, 6, 7, 4]

#7. Grupp av()

groupby(iterable, key) tar in en iterabel och en nyckel, och gör sedan en iterator som returnerar på varandra följande nycklar och grupper. För att det ska fungera måste den iterable som skickas till den sorteras på samma nyckelfunktion. Nyckelfunktionsdatorn ett nyckelvärde för varje element i den iterable.

import itertools

input_list = [("Domestic", "Cow"), ("Domestic", "Dog"), ("Domestic", "Cat"),("Wild", "Lion"), ("Wild", "Zebra"), ("Wild", "Elephant")]
classification = itertools.groupby(input_list,lambda x: x[0])
for key,value in classification:
  print(key,":",list(value))

Produktion:

Domestic : [('Domestic', 'Cow'), ('Domestic', 'Dog'), ('Domestic', 'Cat')]
Wild : [('Wild', 'Lion'), ('Wild', 'Zebra'), ('Wild', 'Elephant')]

#8. islice()

islice(iterbar, start, stopp, steg) låter dig dela upp en iterabel med hjälp av start-, stopp- och stegvärdena. Stegargumentet är valfritt. Räkningen börjar från 0 och posten på stoppnumret ingår inte.

import itertools

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]

# Select elements within a range
selected_numbers = list(itertools.islice(numbers, 2, 10))
selected_numbers_step= list(itertools.islice(numbers, 2, 10,2))
print("islice without setting a step value")
print(selected_numbers)
print("islice with a step value of 2")
print(selected_numbers_step)

Produktion:

islice without setting a step value
[3, 4, 5, 6, 7, 8, 9, 10]
islice with a step value of 2
[3, 5, 7, 9]

#9. parvis()

pairwise(iterable) returnerar successiva överlappande par tagna från den iterable som skickats till den i den ordning de visas i iterabeln. Om iterabeln som skickas till den har mindre än två värden kommer resultatet från pairwise() att vara tomt.

from itertools import pairwise

numbers = [1, 2, 3, 4, 5, 6, 7, 8]
word = 'WORLD'
single = ['A']

print(list(pairwise(numbers)))
print(list(pairwise(word)))
print(list(pairwise(single)))

Produktion:

[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8)]
[('W', 'O'), ('O', 'R'), ('R', 'L'), ('L', 'D')]
[]

#10. stjärnkarta()

starmap(function, iterable) är en funktion som används istället för map() när argumentparametrar redan är grupperade i tupler. startmap() tillämpar en funktion på elementen i iterabeln som skickas till den. Den iterable bör ha element grupperade i tupler.

import itertools

iter_starmap = [(123, 63, 13), (5, 6, 52), (824, 51, 9), (26, 24, 16), (14, 15, 11)]
print (list(itertools.starmap(min, iter_starmap)))

Produktion:

[13, 5, 9, 16, 11]

#11. ta medan()

takewhile(funktion, iterable) fungerar på motsatt sätt till dropwhile(). takewhile() tar in en funktion med ett villkor som ska utvärderas och en iterabel. Den inkluderar sedan alla element i iterabeln som uppfyller villkoret i funktionen tills False returneras. När False returneras ignoreras alla följande element i iterablen.

import itertools

numbers = [1, 2, 3, 4, 5, 1, 6, 7, 2, 1, 8, 9, 0, 7]

# Drop elements until the passed condition is False
filtered_numbers = list(itertools.takewhile(lambda x: x < 5, numbers))
print(filtered_numbers)

Produktion:

[1, 2, 3, 4]

#12. tee()

tee(iterbar, n) tar in en iterabel och returnerar flera oberoende iteratorer. Antalet iteratorer som ska returneras ställs in av n, vilket som standard är 2.

import itertools

numbers = [1, 2, 3, 4, 5]

# Create two independent iterators from numbers
iter1, iter2 = itertools.tee(numbers, 2)
print(list(iter1))
print(list(iter2))

Produktion:

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

#13. zip_longest()

zip_longest(iterables, fillvalue) tar in flera iteratorer och ett fillvalue. Den returnerar sedan en iterator som aggregerar element från var och en av de iteratorer som skickas till den. Om iteratorerna inte är av samma längd, ersätts de saknade värdena med fyllningsvärdet som skickas till funktionen tills den längsta iterable har förbrukats.

import itertools

names = ['John', 'mathew', 'mary', 'Alice', 'Bob', 'Charlie', 'Fury']
ages = [25, 30, 12, 13, 42]

# Combine name and ages, filling in missing ages with a dash
combined = itertools.zip_longest(names, ages, fillvalue="-")

for name, age in combined:
    print(name, age)

Produktion:

John 25
mathew 30
mary 12
Alice 13
Bob 42
Charlie -
Fury -

Slutsats

Python itertools är en viktig verktygsuppsättning för en Python-utvecklare. Python itertools används flitigt i funktionell programmering, databehandling och transformation, datafiltrering och urval, gruppering och aggregering, kombinera iterables, kombinatorik och när man arbetar med oändliga sekvenser.

Som Python-utvecklare kommer du att ha stor nytta av att lära dig om itertools, så se till att använda den här artikeln för att bekanta dig med Python Itertools.