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!

 

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 slice seq[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 slice seq[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 che start + k*passo < stop e start + (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.