Zgodnie z dokumentacją Pythona, Itertools to moduł Pythona, który zapewnia zestaw szybkich i oszczędzających pamięć narzędzi do pracy z iteratorami Pythona. Narzędzia te mogą być używane samodzielnie lub w połączeniu i umożliwiają zwięzłe i wydajne tworzenie i pracę z iteratorami w szybki i efektywny pod względem pamięci sposób.
Moduł Itertools zawiera funkcje ułatwiające pracę z iteratorami, szczególnie przy obsłudze dużych zbiorów danych. Funkcje Itertools mogą działać na istniejących iteratorach, tworząc jeszcze bardziej złożone iteratory Pythona.
Ponadto Itertools może pomóc programistom zmniejszyć liczbę błędów podczas pracy z iteratorami i pisać czystszy, czytelny i łatwy w utrzymaniu kod.
W oparciu o funkcjonalność, jaką zapewniają iteratory w module Itertools, można je podzielić na następujące typy:
Spis treści:
# 1. Nieskończone iteratory
Są to iteratory, które pozwalają pracować z nieskończonymi sekwencjami i uruchamiać pętlę w nieskończoność, jeśli nie ma warunku wyjścia z pętli. Takie iteratory są przydatne podczas symulacji nieskończonych pętli lub generowania nieograniczonej sekwencji. Itertools ma trzy nieskończone iteratory, które obejmują count(), cycle() i repeat().
#2. Iteratory kombinatoryczne
Iteratory kombinatoryczne obejmują funkcje, których można używać do pracy na iloczynach kartezjańskich oraz do wykonywania kombinacji i permutacji elementów zawartych w iterowalnym. Są to podstawowe funkcje, gdy próbujesz znaleźć wszystkie możliwe sposoby ułożenia lub połączenia elementów w iterowalnym. Itertools ma cztery iteratory kombinatoryczne. Są to produkt(), permutacje(), kombinacje() i kombinacje_z_zamianą().
#3. Iteratory kończące się na najkrótszej sekwencji wejściowej
Są to iteratory kończące, które są używane na skończonych sekwencjach i generują dane wyjściowe na podstawie typu użytej funkcji. Przykłady takich iteratorów kończących to: accept(), chain(), chain.from_iterable(), compress(), dropwhile(), filterfalse(), groupby(), islice(), pairwise(), starmap(), takewhile (), tee() i zip_najdłuższy().
Przyjrzyjmy się, jak działają różne funkcje Itertools w zależności od ich typu:
Nieskończone iteratory
Trzy nieskończone iteratory obejmują:
# 1. liczyć()
Funkcja count(start, step) generuje nieskończoną sekwencję liczb zaczynając od wartości początkowej. Funkcja przyjmuje dwa opcjonalne argumenty: start i krok. Argument start ustawia miejsce, w którym sekwencja liczb powinna się zaczynać. Domyślnie zaczyna się od 0, jeśli nie podano wartości początkowej. krok ustawia różnicę między każdą kolejną liczbą. Domyślna wartość kroku to 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
Wyjście
4 6 8 10 12
#2. cykl()
cycle(iterable) funkcja przyjmuje iterowalny jako argument, a następnie cyklicznie przechodzi przez iterowalny, umożliwiając dostęp do elementów w iterowalnym porządku w kolejności, w jakiej się pojawiają.
Na przykład, jeśli przechodzimy [“red”, “green”, “yellow”] do cyklu(), w pierwszym cyklu będziemy mieli dostęp do „czerwonego”; w drugim cyklu będziemy mieli dostęp do „zielonego”, potem „żółtego”. W czwartym cyklu, ponieważ wszystkie elementy zostały wyczerpane w iterowalności, zaczniemy od „czerwonego” i będziemy kontynuować w nieskończoność.
Wywołując cykl () przechowujesz jego wynik w zmiennej, aby utworzyć iterator, który utrzymuje swój stan. Dzięki temu cykl nie zaczyna się za każdym razem od nowa, dając dostęp tylko do pierwszego elementu.
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))
Wyjście:
red green yellow red green yellow red
#3. powtarzać()
repeat(elem,n) przyjmuje dwa argumenty, element do powtórzenia (elem) oraz liczbę powtórzeń elementu (n). Element, który chcesz powtórzyć, może być pojedynczą wartością lub elementem iterowalnym. Jeśli nie podasz n, element będzie powtarzany w nieskończoność.
import itertools for i in itertools.repeat(10, 3): print(i)
Wyjście:
10 10 10
Iteratory kombinatoryczne
Iteratory kombinatoryczne obejmują:
# 1. produkt()
product() to funkcja służąca do obliczania iloczynu kartezjańskiego iterowalności przekazanej do niej. Jeśli mamy dwa zbiory iterowalne, na przykład x = {7,8} i y = {1,2,3}, iloczyn kartezjański x i y będzie zawierał wszystkie możliwe kombinacje elementów z x i y, gdzie pierwszy element pochodzi z x, a drugi z y. Iloczyn kartezjański x i y w tym przypadku wynosi [(7, 1), (7, 2), (7, 3), (8, 1), (8, 2), (8, 3)].
product() przyjmuje opcjonalny parametr o nazwie repeat, który jest używany do obliczania iloczynu kartezjańskiego iterowalnego z samym sobą. repeat określa liczbę powtórzeń dla każdego elementu z iteracji wejściowych podczas obliczania iloczynu kartezjańskiego.
Na przykład wywołanie product(’ABCD’, repeat=2) daje kombinacje takie jak (’A’, 'A’), (’A’, 'B’), (’A’, 'C’) itd. NA. Jeśli powtórzenie zostało ustawione na 3, funkcja zwróciłaby kombinacje, takie jak (’A’, 'A’, 'A’), (’A’, 'A’, 'B’), (’A’, 'A’ , „C”), („A”, „A”, „D”) i tak dalej.
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])))
Wyjście
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. permutacje()
permutations(iterable, group_size) zwraca wszystkie możliwe permutacje przekazanej do niej iterowalności. Permutacja reprezentuje liczbę sposobów uporządkowania elementów w zbiorze. permutations() przyjmuje opcjonalny argument rozmiar_grupy. Jeśli rozmiar_grupy nie zostanie określony, wygenerowane permutacje będą miały taki sam rozmiar, jak długość elementu iterowalnego przekazanego do funkcji
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)
Wyjście
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. kombinacje()
Combines(iterable, size) zwraca wszystkie możliwe kombinacje elementu iterowalnego o danej długości z elementów elementu iterowalnego przekazanego do funkcji. Argument size określa rozmiar każdej kombinacji.
Wyniki są uporządkowane. Kombinacja różni się nieco od permutacji. W przypadku permutacji kolejność ma znaczenie, ale w przypadku kombinacji kolejność nie ma znaczenia. Na przykład w [A, B, C] istnieje 6 permutacji: AB, AC, BA, BC, CA, CB, ale tylko 3 kombinacje 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)
Wyjście:
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. kombinacje_z_wymianą()
Combines_with_replacement(iterable, size) generuje wszystkie możliwe kombinacje iterowalności o danej długości z iterowalności przekazanej do funkcji i dopuszcza powtarzające się elementy w kombinacjach wyjściowych. Rozmiar określa rozmiar generowanych kombinacji.
Ta funkcja różni się od kombinacji() tym, że daje kombinacje, w których element może zostać powtórzony więcej niż jeden raz. Na przykład możesz uzyskać kombinację taką jak (1,1), której nie możesz uzyskać za pomocą kombinacji().
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)
Wyjście
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)]
Zakończenie iteratorów
Obejmuje to iteratory, takie jak:
# 1. gromadzić()
akumuluj(iterowalna, funkcja) przyjmuje iterowalny i drugi opcjonalny argument, który jest funkcją. Następnie zwraca skumulowany wynik zastosowania funkcji w każdej iteracji na elementach iterowalnych. Jeśli żadna funkcja nie zostanie przekazana, wykonywane jest dodawanie i zwracane są skumulowane wyniki.
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))
Wyjście:
Accumulate with no function [1, 3, 6, 10, 15] Accumulate with multiplication [1, 2, 6, 24, 120]
#2. łańcuch()
chain(iterable_1, iterable_2, …) bierze wiele iteracji i łączy je razem, tworząc pojedynczą iterowalność zawierającą wartości z iteracji przekazanych do funkcji chain()
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)
Wyjście:
['A', 'B', 'C', 'D', 1, 2, 3, 'red', 'green', 'yellow']
#3. łańcuch.z_iterable()
chain.from_iterable(iterable) ta funkcja jest podobna do chain(). Jednak różni się od łańcucha tym, że bierze tylko jedną iterowalną zawierającą pod-iterable i łączy je razem.
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)
Wyjście:
['h', 'e', 'l', 'l', 'o', 'red', 'green', 'yellow', 'A', 'B', 'C', 'D', 1, 2, 3]
#4. Kompresja()
compress(dane, selektory) przyjmuje dwa argumenty, dane, które są iterowalne, oraz selektory, które są iterowalne i zawierają wartości logiczne true i false. 1, 0 mogą być również używane jako alternatywy dla wartości boolowskich prawda i fałsz. compress() następnie filtruje przekazane dane przy użyciu odpowiednich elementów przekazanych w selektorze.
Wartości w danych odpowiadające wartości true lub 1 w selektorze są wybierane, podczas gdy pozostałe odpowiadające wartości false lub 0 są ignorowane. Jeśli przekażesz mniej wartości logicznych w selektorach niż liczba elementów w danych, wszystkie elementy poza przekazanymi wartościami boolowskimi w selektorach zostaną zignorowane
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)
Wyjście:
['A', 'C', 'F', 'G', 'I']
#5. dropwhile()
dropwhile(funkcja, sekwencja) przyjmuje funkcję z warunkiem zwracającym prawdę lub fałsz oraz sekwencję wartości. Następnie odrzuca wszystkie wartości, dopóki spełniony warunek nie zwróci False. Gdy warunek zwróci wartość false, pozostałe elementy zostaną uwzględnione w wynikach, niezależnie od tego, czy zwrócą wartość True, czy 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)
Wyjście:
[5, 1, 6, 7, 2, 1, 8, 9, 0, 7]
#6. filtruj fałsz()
filterfalse(funkcja, sekwencja) przyjmuje funkcję z warunkiem, którego wynikiem jest prawda lub fałsz, oraz sekwencją. Następnie zwraca wartości z sekwencji, które nie spełniają warunku w funkcji.
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)
Wyjście:
[4, 5, 6, 5, 8, 6, 7, 4]
#7. Grupuj według()
groupby(iterable, key) pobiera iterowalny i klucz, a następnie tworzy iterator, który zwraca kolejne klucze i grupy. Aby to zadziałało, przekazana do niego iteracja musi być posortowana według tej samej funkcji klucza. Kluczowa funkcja komputera jest kluczową wartością dla każdego elementu w iterowalnym.
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))
Wyjście:
Domestic : [('Domestic', 'Cow'), ('Domestic', 'Dog'), ('Domestic', 'Cat')] Wild : [('Wild', 'Lion'), ('Wild', 'Zebra'), ('Wild', 'Elephant')]
#8. islice()
islice(iterable, start, stop, step) pozwala ci podzielić iterowalny przy użyciu przekazanych wartości start, stop i step. Argument kroku jest opcjonalny. Liczenie rozpoczyna się od 0, a pozycja na numerze przystanku nie jest uwzględniana.
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)
Wyjście:
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. parami()
pairwise(iterable) zwraca kolejne nakładające się pary pobrane z iterowalnego przekazanego do niej w kolejności, w jakiej pojawiają się w iterowalnym. Jeśli przekazana do niego iterowalność ma mniej niż dwie wartości, wynik z pairwise() będzie pusty.
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)))
Wyjście:
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8)] [('W', 'O'), ('O', 'R'), ('R', 'L'), ('L', 'D')] []
#10. mapa gwiezdna()
starmap(function, iterable) to funkcja używana zamiast map(), gdy parametry argumentów są już zgrupowane w krotki. startmap() stosuje funkcję do elementów przekazanej do niej iterowalności. Iterowalny powinien mieć elementy pogrupowane w krotki.
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)))
Wyjście:
[13, 5, 9, 16, 11]
#11. na chwilę()
takewhile(funkcja, iterowalność) działa w odwrotny sposób niż dropwhile(). takewhile() przyjmuje funkcję z warunkiem do oceny i iteracją. Następnie zawiera wszystkie elementy iterowalne, które spełniają warunek w funkcji, dopóki nie zostanie zwrócona wartość False. Po zwróceniu wartości False wszystkie następujące elementy w iterowalności są ignorowane.
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)
Wyjście:
[1, 2, 3, 4]
#12. trójnik()
tee(iterable, n) przyjmuje iterowalny i zwraca wiele niezależnych iteratorów. Liczba zwracanych iteratorów jest ustawiana przez n, które domyślnie wynosi 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))
Wyjście:
[1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
#13. zip_najdłuższy()
zip_longest(iterables, fillvalue) przyjmuje wiele iteratorów i wartość wypełnienia. Następnie zwraca iterator, który agreguje elementy z każdego z przekazanych mu iteratorów. Jeśli iteratory nie mają tej samej długości, brakujące wartości są zastępowane przez wartość wypełnienia przekazywaną do funkcji, aż do wyczerpania najdłuższej iterowalności.
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)
Wyjście:
John 25 mathew 30 mary 12 Alice 13 Bob 42 Charlie - Fury -
Wniosek
Python itertools to ważny zestaw narzędzi dla programisty Pythona. Python itertools są szeroko stosowane w programowaniu funkcjonalnym, przetwarzaniu i transformacji danych, filtrowaniu i selekcji danych, grupowaniu i agregacji, łączeniu iteracji, kombinatoryce oraz podczas pracy z nieskończonymi sekwencjami.
Jako programista Pythona wiele zyskasz, poznając itertools, więc skorzystaj z tego artykułu, aby zapoznać się z Python Itertools.