4 Funzioni di Filtraggio di Itertools in Python Che Probabilmente Non Conosci
4 Funzioni di Filtraggio di Itertools in Python
In Python, gli iteratori ti aiutano a scrivere codice più Pythonico e a lavorare in modo più efficiente con sequenze lunghe. Il modulo itertools integrato fornisce diverse funzioni utili che creano iteratori.
Questi sono particolarmente utili quando si desidera semplicemente attraversare l’iteratore, recuperare gli elementi della sequenza e elaborarli, il tutto senza doverli memorizzare in memoria. Oggi impareremo come utilizzare le seguenti quattro funzioni di filtro itertools:
- filterfalse
- takewhile
- dropwhile
- islice
Iniziamo!
- ChatGPT Enterprise – Andare dove nessun LLM è mai stato prima
- Chi guadagnerà dalla corsa all’oro dell’IA generativa?
- Truccchi di Machine Learning, Apprendimento con ChatGPT e Altre Letture Imperdibili Recentemente
Prima di iniziare: una nota sugli esempi di codice
In questo tutorial:
- Tutte e quattro le funzioni di cui parleremo restituiscono iteratori. Per chiarezza, lavoreremo con sequenze semplici e useremo
list()
per ottenere una lista contenente tutti gli elementi restituiti dall’iteratore. Ma evita di farlo, a meno che non sia necessario, quando lavori con sequenze lunghe. Perché se lo fai, perderai il risparmio di memoria che gli iteratori ti offrono. - Per funzioni predicato semplici, puoi anche usare le lambda. Ma per una migliore leggibilità, definiremo funzioni regolari e le useremo come predicati.
1. filterfalse
Se hai programmato in Python per un po’ di tempo, probabilmente hai usato la funzione integrata filter
con la sintassi:
filter(pred,seq)
# pred: funzione predicato
# seq: qualsiasi iterabile Python valido
La funzione filter
restituisce un iteratore che restituisce elementi dalla sequenza per i quali il predicato restituisce True
.
Prendiamo un esempio:
nums = list(range(1,11)) #[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def is_even(n):
return n % 2 == 0
Qui, la lista nums
e la funzione is_even
sono la sequenza e il predicato, rispettivamente.
Per ottenere la lista di tutti i numeri pari in nums
, utilizziamo filter
come mostrato:
nums_even = filter(is_even, nums)
print(list(nums_even))
Output >>> [2, 4, 6, 8, 10]
Ora impariamo di filterfalse
. Importeremo la funzione filterfalse
(e tutte le altre funzioni di cui parleremo) dal modulo itertools.
Come suggerisce il nome, filterfalse
fa l’opposto di ciò che fa la funzione filter
. Restituisce un iteratore che restituisce elementi per i quali il predicato restituisce False
. Ecco la sintassi da utilizzare per la funzione filterfalse
:
from itertools import filterfalse
filterfalse(pred,seq)
La funzione is_even
restituisce False
per tutti i numeri dispari in nums
. Quindi la lista nums_odd
ottenuta utilizzando filterfalse
è la lista di tutti i numeri dispari in nums
:
from itertools import filterfalse
nums_odd = filterfalse(is_even, nums)
print(list(nums_odd))
Output >>> [1, 3, 5, 7, 9]
2. takewhile
La sintassi da utilizzare per la funzione takewhile
è:
from itertools import takewhile
takewhile(pred,seq)
La funzione takewhile
restituisce un iteratore che restituisce elementi finché la funzione predicato restituisce True
. Smette di restituire elementi quando il predicato restituisce False
per la prima volta.
Per una sequenza di lunghezza n, se seq[k]
è il primo elemento per il quale la funzione predicato restituisce False
, allora l’iteratore restituisce seq[0]
, seq[1]
,…, seq[k-1]
.
Considera la seguente lista nums
e la funzione predicato is_less_than_5
. Utilizziamo la funzione takewhile
come mostrato:
from itertools import takewhile
def is_less_than_5(n):
return n < 5
nums = [1, 3, 5, 2, 4, 6]
filtered_nums_1 = takewhile(is_less_than_5, nums)
print(list(filtered_nums_1))
Qui, il predicato is_less_than_5
restituisce False
—per la prima volta—per il numero 5:
Output >>> [1, 3]
3. dropwhile
Funzionalmente, la funzione dropwhile
fa l’opposto di ciò che fa la funzione takewhile
.
Ecco come puoi usare la funzione dropwhile
:
from itertools import dropwhile
dropwhile(pred,seq)
La funzione dropwhile
restituisce un iteratore che continua a eliminare elementi—finché il predicato è True
. Significa che l’iteratore non restituisce nulla fino a quando il predicato restituisce False
per la prima volta. E una volta che il predicato restituisce False
, l’iteratore restituisce tutti gli elementi successivi nella sequenza.
Per una sequenza di lunghezza n, se seq[k]
è il primo elemento per il quale la funzione predicato restituisce False
, allora l’iteratore restituisce seq[k]
, seq[k+1]
,…, seq[n-1]
.
Utilizziamo la stessa sequenza e predicato:
from itertools import dropwhile
def is_less_than_5(n):
return n < 5
nums = [1, 3, 5, 2, 4, 6]
filtered_nums_2 = dropwhile(is_less_than_5, nums)
print(list(filtered_nums_2))
Perché la funzione predicato is_less_than_5
restituisce False
—per la prima volta—per l’elemento 5, otteniamo tutti gli elementi della sequenza a partire da 5:
Output >>> [5, 2, 4, 6]
4. islice
Già conosci il concetto di slicing degli oggetti iterabili in Python come liste, tuple e stringhe. Lo slicing ha la sintassi: iterable[start:stop:step]
.
Tuttavia, questo approccio allo slicing ha i seguenti svantaggi:
- Quando si lavora con sequenze grandi, ogni slice o sotto-sequenza è una copia che occupa memoria. Questo può essere inefficiente.
- Poiché lo step può anche avere valori negativi, l’utilizzo dei valori di start, stop e step influisce sulla leggibilità.
La funzione islice
affronta le limitazioni sopra descritte:
- Restituisce un iteratore.
- Non consente valori negativi per lo step.
Puoi utilizzare la funzione islice
in questo modo:
from itertools import islice
islice(seq,start,stop,step)
Ecco alcuni modi diversi in cui puoi utilizzare la funzione islice
:
- Utilizzando
islice(seq, stop)
restituisce un iteratore sulla sliceseq[0]
,seq[1]
,…,seq[stop - 1]
. - Se specifici i valori di inizio e di fine:
islice(seq, start, stop)
la funzione restituisce un iteratore sulla sliceseq[start]
,seq[start + 1]
,…,seq[start + stop - 1]
. - Quando specifici gli argomenti di inizio, fine e passo, la funzione restituisce un iteratore sulla slice
seq[start]
,seq[start + passo]
,seq[start + 2*passo]
,…,seq[start + k*passo]
. Tale chestart + k*passo
<stop
estart + (k+1)*passo
>=stop
.
Prendiamo un esempio di lista per capire meglio:
nums = list(range(10)) #[0,1, 2, 3, 4, 5, 6, 7, 8, 9]
Ora utilizziamo la funzione islice
con la sintassi che abbiamo imparato.
Utilizzando solo il valore di fine
Specificare solo l’indice di fine:
from itertools import islice
# solo fine
sliced_nums = islice(nums, 5)
print(list(sliced_nums))
Ecco l’output:
Output >>> [0, 1, 2, 3, 4]
Utilizzando i valori di inizio e fine
Qui, utilizziamo sia i valori di inizio che di fine:
# inizio e fine
sliced_nums = islice(nums, 2, 7)
print(list(sliced_nums))
La slice inizia dall’indice 2 e si estende fino a, ma senza includere, l’indice 7:
Output >>> [2, 3, 4, 5, 6]
Utilizzando i valori di inizio, fine e passo
Quando utilizziamo i valori di inizio, fine e passo:
# utilizzando inizio, fine e passo
sliced_nums = islice(nums, 2, 8, 2)
print(list(sliced_nums))
Otteniamo una slice che inizia dall’indice 2, si estende fino a, ma senza includere, l’indice 8, con un passo di 2 (restituendo ogni secondo elemento).
Output >>> [2, 4, 6]
Conclusione
Spero che questo tutorial ti abbia aiutato a capire le basi delle funzioni di filtro itertools. Hai visto alcuni esempi semplici per capire meglio il funzionamento di queste funzioni. Successivamente, puoi imparare come funzionano i generatori, le funzioni dei generatori e le espressioni dei generatori come efficienti iteratori Python. Bala Priya C è una sviluppatrice e scrittrice tecnica dell’India. Le piace lavorare all’intersezione tra matematica, programmazione, data science e creazione di contenuti. Le sue aree di interesse e competenza includono DevOps, data science e elaborazione del linguaggio naturale. Ama leggere, scrivere, programmare e il caffè! Attualmente, sta lavorando per imparare e condividere le sue conoscenze con la community di sviluppatori attraverso la scrittura di tutorial, guide pratiche, articoli di opinione e altro ancora.