Corso Python / Comprehension per liste, dizionari e insiemi

Una comprehension crea una collezione trasformando elementi o scegliendo quelli che rispettano una condizione. Usala per un’operazione breve e leggibile; preferisci un ciclo normale quando servono più passaggi, gestione di eccezioni o effetti come stampe e salvataggi.

Separare trasformazione e filtro

La forma per le liste è [espressione for elemento in sorgente if condizione]. Il for legge gli elementi e l’if finale decide quali includere; solo per quelli accettati viene valutata l’espressione del risultato. Il ciclo for con unpacking aiuta a leggere lo stesso ordine di elaborazione.

Un’espressione come a if condizione else b ha un altro ruolo: sceglie quale valore produrre per un elemento incluso, senza eliminarlo. Per esempio, puoi prima escludere gli importi negativi e poi assegnare un’etichetta a ciascun importo rimasto, mantenendo anche zero.

La comprehension costruisce una nuova collezione esterna, ma non esegue automaticamente una copia profonda. Se l’espressione restituisce un dizionario già esistente, il risultato continua a riferirsi a quel dizionario. Inoltre, un’espressione che chiama funzioni può avere effetti propri: non considerare la sintassi una garanzia generale di assenza di modifiche.

La guida ufficiale alle list comprehension mostra come passare da un ciclo esplicito a questa forma.

Creare liste, dizionari e insiemi in un esempio completo

Salva il seguente programma in UTF-8 come comprehensions.py, dentro una cartella di esercitazione. Esegui python comprehensions.py con l’interprete del progetto selezionato. Fuori dall’ambiente virtuale su macOS o Ubuntu usa python3 se è il comando dell’interprete scelto. Non occorrono pacchetti esterni.

amounts = [3500, -1, 8000, 0]
valid = [x for x in amounts if x >= 0]
labels = ["paid" if x > 0 else "free" for x in valid]
records = [("food", 3500), ("bus", 2500)]
by_name = {name: amount for name, amount in records}
remainders = {x % 3 for x in valid}
print(valid)
print(labels)
print(by_name)
print(sorted(remainders))

Il risultato atteso è:

[3500, 8000, 0]
['paid', 'paid', 'free']
{'food': 3500, 'bus': 2500}
[0, 2]

valid esclude -1 ma conserva zero. La lista labels attribuisce paid agli importi positivi e free a zero; l’if–else è qui dentro l’espressione del valore. by_name associa ciascun nome al suo importo; remainders raccoglie i resti della divisione per tre, eliminando le ripetizioni. La stampa ordinata dei resti mostra 0 e 2, senza attribuire un ordine all’insieme stesso.

Gestire chiavi duplicate e ordine di elaborazione

In una dictionary comprehension, una chiave ripetuta riceve l’ultimo valore incontrato: {name: amount for name, amount in records} non somma importi con lo stesso nome. Se vuoi totali per categoria, usa un accumulo esplicito come nell’esempio sui dizionari e i totali.

Una set comprehension può produrre meno elementi dei record di partenza perché conserva solo valori unici. La guida agli insiemi e alla perdita delle ripetizioni spiega quando questa trasformazione è appropriata. La scelta delle parentesi e, nel dizionario, della coppia chiave-valore cambia il significato del risultato.

Per seguire il flusso, considera [x * 2 for x in range(4) if x % 2 == 0]: vengono scelti 0 e 2, poi moltiplicati per due, producendo [0, 4]. Espandi prima la regola in un normale for con un if e append se l’ordine non è chiaro. La specifica delle espressioni per collezioni descrive anche i casi con più clausole.

Più cicli annidati dentro una comprehension non diventano più semplici solo perché occupano una riga. Mantieni il ciclo esplicito quando devi gestire errori per record, registrare problemi o applicare più operazioni che renderebbero poco leggibile l’espressione.

Verificare risultati vuoti e condivisione degli oggetti

Se tutti gli elementi vengono esclusi, una list comprehension restituisce una lista vuota. Prima di leggerne la posizione 0 o dividere per la sua lunghezza, decidi se l’assenza di risultati è un caso valido e come rappresentarla. Un filtro riuscito non garantisce un risultato non vuoto.

Non usare una list comprehension solo per stampare o salvare file: produrresti una lista inutilizzata con i risultati di quelle chiamate. Un for comunica direttamente l’effetto desiderato, senza costruire una collezione priva di utilità.

  1. Cambia il filtro numerico da x >= 0 a x > 0. Verifica che zero e la relativa etichetta free scompaiano; anche il resto zero non sarà più prodotto da questi dati.
  2. Ripristina il filtro e aggiungi ("food", 4500) a records. Il valore di food nel dizionario diventa 4500, non 8000: osserva la sostituzione e distinguila dalla somma.
  3. Ripristina tutti i dati e confronta le quattro righe con il risultato atteso.

Per capire la condivisione, immagina una lista di dizionari filtrata restituendo ogni dizionario così com’è: cambiando un campo in uno di quegli oggetti lo vedrai anche nella sorgente. Creare una nuova lista e creare nuovi elementi sono operazioni distinte, come nel comportamento delle copie superficiali.