Corso
Esegui e modifica il codice da questo tutorial online
Esegui codiceFacendo data science, potresti trovarti a leggere liste di liste, filtrare nomi di colonne, rimuovere vocali da una lista o appiattire una matrice. Puoi usare facilmente una funzione lambda o un ciclo for; come ben sai, ci sono diversi modi per farlo. Un altro modo è usare le list comprehension.
In questo tutorial affronterai proprio questo ultimo argomento:
- Per prima cosa, un breve ripasso su cosa sono le liste in Python e come si confrontano con altre strutture dati di Python;
- Poi passerai alle list comprehension in Python: scoprirai di più sulla matematica dietro le liste in Python, come costruire list comprehension, come riscriverle come cicli for o funzioni lambda, ... Non solo leggerai, ma farai anche alcuni esercizi!
- Quando avrai assimilato le basi, è il momento di perfezionare le tue list comprehension aggiungendo condizioni: imparerai come includere condizioni nelle list comprehension e come gestire più condizioni if e istruzioni if-else.
- Infine, approfondirai le list comprehension nidificate per iterare più volte sulle liste.
Ti interessa affrontare le list comprehension insieme a iteratori e generatori? Dai un'occhiata al corso Python Data Science Toolbox di DataCamp!

Liste in Python
A questo punto, probabilmente ti sarai già divertito con valori di vari tipi di dato. Hai salvato ogni valore in una variabile separata: ogni variabile rappresenta un singolo valore. Tuttavia, nella data science lavorerai spesso con molti dati, il che rende difficile continuare a salvare ogni valore in una variabile separata. Invece, raccoglierai tutti questi valori in una lista Python.
Le liste sono una delle quattro strutture dati integrate in Python. Altre strutture che potresti conoscere sono tuple, dizionari e set. Una lista in Python è diversa, ad esempio, da int o bool, nel senso che è un tipo di dato composto: puoi raggruppare valori insieme in liste. In realtà, questi valori non devono essere dello stesso tipo: possono essere una combinazione di booleani, stringhe, interi, ...
È importante notare che le liste sono collezioni ordinate di elementi o oggetti. Questo rende le liste in Python "sequence types", in quanto si comportano come una sequenza. Significa che sono iterabili; altri esempi di sequenze sono stringhe, tuple o set.
Consiglio: se vuoi saperne di più, testare o esercitare le tue conoscenze sulle liste in Python, puoi farlo ripassando le domande più comuni sulle liste in Python qui.
Passando alla pratica: costruisci una lista con due parentesi quadre; all'interno di queste parentesi, usa le virgole per separare i valori. Puoi quindi assegnare la tua lista a una variabile. I valori che metti in una lista Python possono essere di qualsiasi tipo di dato, persino liste!
Dai un'occhiata al seguente esempio di lista:
Consiglio: crea la tua lista nella shell IPython contenuta nel blocco DataCamp Light qui sopra!
List Comprehension in Python
Con il ripasso delle liste Python fresco in mente, è facile vedere che definire e creare liste in Python può essere un lavoro noioso: digitare tutti i valori separatamente può richiedere tempo e si rischia facilmente di commettere errori.
Le list comprehension in Python si costruiscono così:
list_variable = [x for x in iterable]
Ma come si arriva a questo modo, quasi da formula, di costruire e usare queste strutture in Python? Andiamo un po' più a fondo.
List Comprehension in Python: la matematica
Per fortuna, Python ha la soluzione: ti offre un modo per implementare una notazione matematica per fare questo: la list comprehension.
Ricorda che in matematica, i modi comuni per descrivere liste (o insiemi, o tuple, o vettori) sono:
S = {x² : x in {0 ... 9}}
V = (1, 2, 4, 8, ..., 2¹²)
M = {x | x in S and x even}
In altre parole, le definizioni sopra in realtà ti dicono quanto segue:
- La sequenza S contiene valori compresi tra 0 e 9 inclusi elevati alla seconda potenza.
- La sequenza V, invece, contiene il valore 2 elevato a una certa potenza. Per il primo elemento della sequenza è 0, per il secondo è 1, e così via, fino a 12.
- Infine, la sequenza M contiene elementi della sequenza S, ma solo quelli pari.
Se le definizioni sopra ti fanno venire il mal di testa, guarda le liste reali che queste definizioni produrrebbero:
S = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}
V = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096}
M = {0, 4, 16, 36, 64}
Vedi chiaramente il risultato di ciascuna lista e le operazioni descritte!
Ora che hai capito un po' della matematica dietro le liste, puoi tradurre o implementare la notazione matematica per costruire liste in Python usando le list comprehension! Dai un'occhiata alle seguenti righe di codice:
Tutto questo sembra molto simile alle definizioni matematiche che hai appena visto, giusto?
Niente panico se sei un po' spaesato a questo punto; anche se non sei un genio della matematica, le list comprehension sono abbastanza semplici se ti prendi il tempo di studiarle. Osserva con attenzione il codice Python nel blocco qui sopra.
Vedrai che il codice ti dice che:
- La lista S è costruita con le parentesi quadre viste nella prima sezione. In quelle parentesi c'è un elemento x, elevato alla potenza di 10. Ora, devi solo sapere per quanti valori (e quali valori!) devi elevare alla potenza di 2. Questo è determinato da
range(10). Considerando tutto questo, puoi dedurre che eleverai alla seconda potenza tutti i numeri da 0 a 9. - La lista V contiene il valore base 2, che è elevato a una certa potenza. Come prima, ora devi sapere quale potenza o quale
iverrà usata. Vedi che in questo casoifa parte dirange(13), il che significa che parti da 0 e arrivi fino a 12. Tutto ciò significa che la tua lista avrà 13 valori: 2 elevato alla potenza 0, 1, 2, ... fino a 12. - Infine, la lista M contiene elementi che fanno parte di S se -e solo se- sono divisibili per 2 senza resto. Il modulo deve essere 0. In altre parole, la lista M è costruita con i valori pari che sono memorizzati nella lista S.
Ora che è tutto scritto nero su bianco, ha molto più senso, vero?
Ripasso e pratica
In breve, vedi che ci sono alcuni elementi che ritornano in tutte queste righe di codice:
- Le parentesi quadre, che sono il tratto distintivo delle liste Python;
- La parola chiave
for, seguita da una variabile che simboleggia un elemento della lista; e - La parola chiave
in, seguita da una sequenza (che può essere una lista!).
E questo porta al pezzo di codice che hai visto all'inizio di questa sezione:
list_variable = [x for x in iterable]
Ora tocca a te iniziare a usare le list comprehension in Python! Restiamo vicini alle liste matematiche che hai visto prima:
List Comprehension come alternativa a...
La list comprehension è un sostituto completo dei cicli for, delle funzioni lambda e delle funzioni map(), filter() e reduce(). Inoltre, per alcune persone, la list comprehension può risultare persino più semplice da capire e usare nella pratica! Ne leggerai di più nella prossima sezione!
Tuttavia, se vuoi saperne di più su funzioni e funzioni lambda in Python, dai un'occhiata al nostro Tutorial sulle funzioni in Python.
Cicli for
Come forse già sai, usi i cicli for per ripetere un blocco di codice un numero fisso di volte. Le list comprehension sono in realtà ottime alternative ai cicli for, perché sono più compatte. Considera il seguente esempio che parte dalla variabile numbers, definita come un range da 0 fino a 10 (escluso).
Ricorda che il numero che passi alla funzione range() è in realtà la quantità di interi che vuoi generare, a partire da zero, naturalmente. Questo significa che range(10) restituirà [0,1,2,3,4,5,6,7,8,9].
# Initialize `numbers`
numbers = range(10)
Se ora vuoi eseguire un'operazione su ogni elemento in numbers, puoi farlo con un ciclo for, proprio così:
# Initialize `new_list`
new_list = []
# Add values to `new_list`
for n in numbers:
if n%2==0:
new_list.append(n**2)
# Print `new_list`
print(new_list)
[0, 4, 16, 36, 64]
Tutto bene, ma ora considera il seguente esempio di list comprehension, in cui fai sostanzialmente la stessa cosa con una notazione più compatta:
# Create `new_list`
new_list = [n**2 for n in numbers if n%2==0]
# Print `new_list`
print(new_list)
[0, 4, 16, 36, 64]
Studiamo la differenza di prestazioni tra la list comprehension e il ciclo for con un piccolo test: puoi configurarlo molto rapidamente con la libreria timeit, che puoi usare per cronometrare piccoli pezzi di codice Python in modo semplice. In questo caso, i piccoli pezzi di codice che testerai sono il ciclo for, che inserirai in una funzione chiamata power_two() per comodità, e la list comprehension esatta che hai formulato sopra.
Nota che passi anche il numero di esecuzioni che vuoi considerare. In questo caso è impostato a 10000 nell'argomento number.
# Import `timeit`
import timeit
# Print the execution time
print(timeit.timeit('[n**2 for n in range(10) if n%2==0]', number=10000))
0.05234622399802902
# Define `power_two()`
def power_two(numbers):
for n in numbers:
if n%2==0:
new_list.append(n**2)
return new_list
# Print the execution time
print(timeit.timeit('power_two(numbers)', globals=globals(), number=10000))
0.07795589299712447
Nota che in quest'ultimo pezzo di codice aggiungi anche l'argomento globals, che farà eseguire il codice all'interno del tuo attuale namespace globale. Questo è estremamente utile se hai una funzione definita dall'utente (UDF) come la funzione power_two() nell'esempio sopra. In alternativa, puoi anche passare un parametro setup che contiene un'istruzione di import. Puoi leggere di più a riguardo qui.
Consiglio: dai un'occhiata al tutorial Loops in Python di DataCamp per ulteriori informazioni sui loop in Python.
Funzioni lambda con map(), filter() e reduce()
Le funzioni lambda sono chiamate anche "funzioni anonime" o "funzioni senza nome". Significa che usi questo tipo di funzioni solo quando vengono create. Le funzioni lambda prendono il nome dalla parola chiave lambda in Python, che viene usata per dichiararle al posto della parola chiave standard def.
Di solito usi queste funzioni insieme alle funzioni map(), filter() e reduce().
Come sostituire map() in combinazione con le funzioni lambda
Puoi riscrivere la combinazione di map() e una funzione lambda proprio come nell'esempio qui sotto:
# Initialize the `kilometer` list
kilometer = [39.2, 36.5, 37.3, 37.8]
# Construct `feet` with `map()`
feet = map(lambda x: float(3280.8399)*x, kilometer)
# Print `feet` as a list
print(list(feet))
[128608.92408000001, 119750.65635, 122375.32826999998, 124015.74822]
Ora puoi sostituire facilmente questa combinazione di funzioni che definisce la variabile feet con le list comprehension, tenendo a mente i componenti di cui hai letto nella sezione precedente:
- Inizia con le parentesi quadre.
- Poi aggiungi il corpo della funzione lambda in quelle parentesi quadre:
float(3280.8399)*x. - Successivamente, aggiungi la parola chiave
fore assicurati di ripetere l'elemento di sequenzax, che hai già citato aggiungendo il corpo della funzione lambda. - Non dimenticare di specificare da dove proviene
x: aggiungi la parola chiavein, seguita dalla sequenza da cui otterraix. In questo caso, trasformerai gli elementi della listakilometer.
Se fai tutto questo, otterrai il seguente risultato:
# Convert `kilometer` to `feet`
feet = [float(3280.8399)*x for x in kilometer]
# Print `feet`
print(feet)
[128608.92408000001, 119750.65635, 122375.32826999998, 124015.74822]
filter() e funzioni lambda in list comprehension
Ora che hai visto quanto facilmente puoi convertire la funzione map() in combinazione con una funzione lambda, puoi affrontare anche il codice che contiene la funzione Python filter() con funzioni lambda e riscriverlo allo stesso modo.
Considera il seguente esempio:
# Map the values of `feet` to integers
feet = list(map(int, feet))
# Filter `feet` to only include uneven distances
uneven = filter(lambda x: x%2, feet)
# Check the type of `uneven`
type(uneven)
# Print `uneven` as a list
print(list(uneven))
[122375, 124015]
Per riscrivere le righe di codice nell'esempio sopra, puoi effettivamente usare due list comprehension, salvate nelle variabili feet e uneven.
Per prima cosa, riscrivi la funzione map(), che usi per convertire gli elementi della lista feet in interi. Poi affronti la funzione filter(): prendi il corpo della funzione lambda, usa le parole chiave for e in per collegare logicamente x e feet:
# Constructing `feet`
feet = [int(x) for x in feet]
# Print `feet`
print(feet)
# Get all uneven distances
uneven = [x%2 for x in feet]
# Print `uneven`
print(uneven)
[128608, 119750, 122375, 124015]
[0, 0, 1, 1]
Reduce reduce() e funzioni lambda in Python
Infine, puoi anche riscrivere le funzioni lambda usate con reduce() in righe di codice più compatte. Guarda il seguente esempio:
# Import `reduce` from `functools`
from functools import reduce
# Reduce `feet` to `reduced_feet`
reduced_feet = reduce(lambda x,y: x+y, feet)
# Print `reduced_feet`
print(reduced_feet)
[128608, 119750, 122375, 124015]
494748
Nota che in Python 3 la funzione reduce() è stata spostata nel package functools. Dovrai quindi importare il modulo per usarla, proprio come nell'esempio sopra.
Il blocco di codice sopra è piuttosto lungo, vero?
Riscriviamolo!
Attenzione! Devi tenere conto che non puoi usare y. Le list comprehension funzionano con un solo elemento alla volta, come l'x che hai visto in molti esempi di questo tutorial.
Come risolvere?
Be', in casi come questi, funzioni di aggregazione come sum() possono tornare utili:
# Construct `reduced_feet`
reduced_feet = sum([x for x in feet])
# Print `reduced_feet`
print(reduced_feet)
494748
Nota che, a ben pensarci, l'uso di funzioni di aggregazione quando si riscrive la funzione reduce() in combinazione con una funzione lambda ha senso: è molto simile a ciò che fai in SQL quando usi funzioni di aggregazione per limitare il numero di record restituiti dopo l'esecuzione della query. In questo caso, usi la funzione sum() per aggregare gli elementi in feet e ottenere un solo valore definitivo!
Nota che anche se questo approccio potrebbe non essere il più performante in SQL, è sicuramente la strada giusta quando lavori in Python!
List comprehension con condizioni
Ora che hai capito le basi delle list comprehension in Python, è il momento di modificare il flusso di controllo delle tue comprehension con l'aiuto delle condizioni.
# Define `uneven`
uneven = [x/2 for x in feet if x%2==0]
# Print `uneven`
print(uneven)
[64304.0, 59875.0]
Nota che puoi riscrivere facilmente il blocco di codice sopra con un ciclo for in Python!
# Initialize and empty list `uneven`
uneven = []
# Add values to `uneven`
for x in feet:
if x % 2 == 0:
x = x / 2
uneven.append(x)
# Print `uneven`
print(uneven)
[64304.0, 59875.0]
Condizioni multiple con if
Ora che hai capito come aggiungere condizioni, è il momento di convertire il seguente ciclo for in una list comprehension con condizioni.
divided = []
for x in range(100):
if x%2 == 0 :
if x%6 == 0:
divided.append(x)
Attenzione, vedi che il seguente ciclo for contiene due condizioni! Pensa bene a come risolverlo.
divided = [x for x in range(100) if x % 2 == 0 if x % 6 == 0]
print(divided)
[0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96]
Condizioni if-else
Certo, è molto più comune lavorare con condizioni che coinvolgono più di un caso. Esatto, vedrai spesso if in combinazione con elif e else. Come gestirlo se vuoi riscrivere il tuo codice?
Guarda il seguente esempio di una condizione più complessa in un ciclo for:
[x+1 if x >= 120000 else x+5 for x in feet]
[128609, 119755, 122376, 124016]
Ora guarda il seguente blocco di codice, che è una riscrittura del pezzo precedente:
for x in feet:
if x >= 120000:
x + 1
else:
x+5
Vedi che è sostanzialmente lo stesso codice, ma ristrutturato: l'ultimo for x in feet ora inizializza il ciclo for. Dopo, aggiungi la condizione if x >= 120000 e la riga di codice che vuoi eseguire se la condizione è True: x + 1. Se invece la condizione è False, viene eseguito l'ultimo pezzo di codice nella list comprehension: x+5.
List comprehension nidificate
Oltre alle condizioni, puoi anche modificare le list comprehension nidificandole all'interno di altre list comprehension. Questo è utile quando vuoi lavorare con liste di liste: generare liste di liste, trasporre liste di liste o appiattire liste di liste in liste normali, per esempio, diventa estremamente semplice con le list comprehension nidificate.
Dai un'occhiata al seguente esempio:
list_of_list = [[1,2,3],[4,5,6],[7,8]]
# Flatten `list_of_list`
[y for x in list_of_list for y in x]
[1, 2, 3, 4, 5, 6, 7, 8]
Assegni una semplice lista di liste alla variabile list_of_list. Nella riga successiva, esegui una list comprehension che restituisce una lista normale. In pratica, prendi gli elementi di lista ( y ) delle liste nidificate ( x ) in list_of_list e restituisci una lista di quegli elementi y contenuti in x.
Vedi che la maggior parte delle parole chiave e degli elementi usati nell'esempio di list comprehension nidificata sono simili a quelli usati negli esempi di list comprehension semplice:
- Parentesi quadre
- Due parole chiave
for, seguite da una variabile che simboleggia un elemento della lista di liste (x) e un elemento di una lista nidificata (y); e - Due parole chiave
in, seguite da una lista di liste (list_of_list) e da un elemento di lista (x).
La maggior parte dei componenti è semplicemente usata due volte e sali di un livello (o scendi, dipende da come la vedi!).
Ci vuole un po' per abituarsi, ma è piuttosto semplice, eh?
Consideriamo ora un altro esempio, in cui vedi che puoi usare anche due coppie di parentesi quadre per cambiare la logica della tua list comprehension nidificata:
matrix = [[1,2,3],[4,5,6],[7,8,9]]
[[row[i] for row in matrix] for i in range(3)]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Ora esercitati: riscrivi il blocco di codice sopra in un ciclo for nidificato. Se ti servono indicazioni su come affrontare questo esercizio, torna a una delle sezioni precedenti di questo tutorial.
transposed = []
for i in range(3):
transposed_row = []
for row in matrix:
transposed_row.append(row[i])
transposed.append(transposed_row)
Puoi usare le list comprehension nidificate anche quando devi creare una lista di liste che è in realtà una matrice. Guarda il seguente esempio:
matrix = [[0 for col in range(4)] for row in range(3)]
matrix
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Consiglio: allena le tue abilità con i loop in Python e riscrivi il blocco di codice sopra in un ciclo for nidificato!
Puoi trovare la soluzione qui sotto.
for x in range(3):
nested = []
matrix.append(nested)
for row in range(4):
nested.append(0)
Se vuoi fare un lavoro extra, prova a tradurre questo ciclo for in un ciclo while. Puoi trovare la soluzione qui sotto:
x = 0
matrix =[]
while x < 3:
nested = []
y = 0
matrix.append(nested)
x = x+1
while y < 4:
nested.append(0)
y= y+1
Infine, è bene sapere che puoi anche usare funzioni come int() per convertire le voci nella tua lista feet in interi. Incapsulando [int(x) for x in feet] all'interno di un'altra list comprehension, costruisci facilmente una matrice o liste della tua lista:
[[int(x) for x in feet] for x in feet]
[[128608, 119750, 122375, 124015],
[128608, 119750, 122375, 124015],
[128608, 119750, 122375, 124015],
[128608, 119750, 122375, 124015]]
Padroneggia Python per la Data Science
Complimenti! Sei arrivato alla fine di questo tutorial, in cui hai affrontato le list comprehension, un meccanismo usato spesso in Python per la data science. Ora che ne capisci il funzionamento, sei pronto per affrontare anche le comprehension di dizionari, set, ...!
Non dimenticare che puoi esercitare quotidianamente le tue abilità in Python con la modalità di pratica giornaliera di DataCamp! La trovi direttamente nella tua dashboard. Se non conosci ancora la pratica giornaliera, leggi di più qui! E scopri l'intero catalogo di corsi Python di DataCamp qui.
Anche se le list comprehension possono rendere il codice più conciso, è importante assicurarsi che il codice finale sia il più leggibile possibile, quindi è meglio evitare singole righe troppo lunghe per mantenere il codice facile da usare.
Domande frequenti sulle List Comprehension in Python
Che cos'è una list comprehension in Python?
Una sintassi concisa per creare una lista a partire da un range o da un oggetto iterabile applicando un'operazione specificata a ciascuno dei suoi elementi. È molto più veloce delle alternative, come i cicli for, le funzioni lambda, le condizioni, ecc.
Quando usiamo le list comprehension?
Quando dobbiamo creare una lista Python a partire da un oggetto range o da un iterabile (un'altra lista, tupla, set, ecc.) applicando una certa operazione a ogni elemento dell'oggetto di input. Funziona al meglio quando l'espressione valutata è relativamente semplice. Due casi particolari di utilizzo delle list comprehension sono il filtraggio di un oggetto di input e l'appiattimento di un iterabile multidimensionale (ad es. una lista di liste).
Su che tipo di sequenze opera la list comprehension?
Un oggetto range o un iterabile, come una stringa, un'altra lista, una lista di liste, una tupla, un set, un dizionario, ecc. Nel caso di list comprehension nidificate, è possibile avere collezioni di dati di tipi diversi.
Quali sono gli elementi principali della sintassi delle list comprehension?
Parentesi quadre che racchiudono la list comprehension, una variabile che fa riferimento a ogni elemento della sequenza di input, un'espressione da valutare, la collezione di dati (o le collezioni) a cui si applica l'espressione, le parole chiave obbligatorie for e in, le parole chiave if, else, not (quando necessario), operatori matematici e di confronto.
Quali costrutti Python può sostituire la list comprehension?
La list comprehension è un'alternativa più concisa ai cicli for (inclusi quelli nidificati), alle funzioni lambda, alle funzioni built-in di Python map(), filter() e reduce(), e alle condizioni.
Quali sono i vantaggi dell'uso delle list comprehension in Python?
Prestazioni elevate, sintassi compatta, codice in una riga facile da leggere e fare debug, uso ottimizzato dello spazio verticale nel programma.
Qual è il principale svantaggio delle list comprehension?
In alcune circostanze le list comprehension possono essere difficili da implementare e da leggere, ad esempio con espressioni troppo complesse da valutare o con troppi cicli nidificati.
Come appiattire una lista di liste?
Usando list comprehension nidificate. Per esempio, data list_of_lists = [[1, 2, 3, 4], [5, 6, 7], [8, 9]], possiamo appiattire questa lista di liste con il seguente pezzo di codice: [item for lst in list_of_lists for item in lst].
È possibile usare un'assegnazione all'interno dell'espressione di una list comprehension?
Sì, a partire da Python 3.8, anche se questa operazione è raramente usata. A questo scopo devi usare l'operatore walrus :=. Per esempio, la seguente list comprehension crea 5 volte un intero casuale tra 1 e 10 inclusi (prima devi importare random), verifica se è maggiore di 3 e, in tal caso, lo assegna alla variabile x, che poi viene aggiunta alla lista in costruzione: [x for _ in range(5) if (x := random.randint(1, 10)) > 3].
Quali altri tipi di comprehension esistono in Python?
Esistono anche le comprehension per set, dizionari e generatori con una sintassi simile a quella delle list comprehension. Non esiste una tuple comprehension in Python.

