Parliamo

project-cherry.dev

Intermedio12 min

List Comprehension

Filtra, trasforma e riorganizza centinaia di fatture in una sola riga di codice con le list comprehension di Python.

List Comprehension

La consulente fiscale Sara Conti ha un problema ricorrente: ogni trimestre deve analizzare 500 fatture, filtrare quelle pagate, calcolare totali per cliente e preparare l'export per il commercialista. Con i cicli for tradizionali servono decine di righe. Le list comprehension riducono tutto a espressioni compatte e leggibili.

Da ciclo a comprehension

Partiamo dal caso classico: filtrare le fatture pagate da una lista di 500 documenti.

python
# --- Approccio tradizionale con ciclo for ---
fatture = [
    {"numero": "2024-001", "cliente": "Rossi", "importo": 1500, "stato": "pagata"},
    {"numero": "2024-002", "cliente": "Bianchi", "importo": 2300, "stato": "scaduta"},
    {"numero": "2024-003", "cliente": "Ferraro", "importo": 800, "stato": "pagata"},
    {"numero": "2024-004", "cliente": "Conti", "importo": 3100, "stato": "in_attesa"},
    {"numero": "2024-005", "cliente": "Verdi", "importo": 1200, "stato": "scaduta"},
]

# Con ciclo for: 4 righe
pagate = []
for fattura in fatture:
    if fattura["stato"] == "pagata":
        pagate.append(fattura)

# Con comprehension: 1 riga
pagate = [f for f in fatture if f["stato"] == "pagata"]
print(f"Fatture pagate: {len(pagate)}")  # Fatture pagate: 2

La struttura è sempre la stessa: [espressione for elemento in sequenza if condizione]. Più compatta, più leggibile, e anche leggermente più veloce.

Filtrare con condizione

Sara deve individuare le fatture problematiche: quelle scadute oppure con importo sopra una certa soglia di attenzione.

python
# Fatture scadute
scadute = [f for f in fatture if f["stato"] == "scaduta"]
print(f"Da sollecitare: {len(scadute)}")  # Da sollecitare: 2

# Fatture sopra soglia (richiedono verifica manuale)
soglia = 2000
importanti = [f for f in fatture if f["importo"] > soglia]
print(f"Sopra soglia: {len(importanti)}")  # Sopra soglia: 2

# Combinare condizioni: scadute E sopra soglia
urgenti = [f for f in fatture if f["stato"] == "scaduta" and f["importo"] > soglia]
print(f"Urgenti: {len(urgenti)}")  # Urgenti: 1

Trasformare per export

Il commercialista vuole un CSV con importi formattati e righe pronte. Le comprehension eccellono nella trasformazione dei dati.

python
# Formattare gli importi con il simbolo euro
importi_formattati = [f"{f['importo']:.2f} EUR" for f in fatture]
print(importi_formattati)
# ['1500.00 EUR', '2300.00 EUR', '800.00 EUR', '3100.00 EUR', '1200.00 EUR']

# Generare righe CSV pronte per l'export
righe_csv = [
    f"{f['numero']};{f['cliente']};{f['importo']};{f['stato']}"
    for f in fatture
    if f["stato"] == "pagata"
]
for riga in righe_csv:
    print(riga)
# 2024-001;Rossi;1500;pagata
# 2024-003;Ferraro;800;pagata

Dict e set comprehension

La stessa sintassi funziona per dizionari (raggruppare dati) e set (valori unici).

python
# Dict comprehension: totale per cliente
totale_per_cliente = {
    f["cliente"]: f["importo"]
    for f in fatture
}
print(totale_per_cliente)
# {'Rossi': 1500, 'Bianchi': 2300, 'Ferraro': 800, ...}

# Set comprehension: codici fiscali unici (no duplicati)
codici_fiscali = [
    "RSSMRC80A01H501Z", "BNCLNE85B41F205X",
    "RSSMRC80A01H501Z", "FRRGPP70C15L219Y"
]
unici = {cf for cf in codici_fiscali}
print(f"Clienti unici: {len(unici)}")  # Clienti unici: 3

Quando NON usare le comprehension

Le comprehension sono potenti, ma non sono sempre la scelta giusta. Se la logica diventa troppo articolata, un ciclo esplicito è più leggibile e manutenibile.

python
# Troppo complesso per una comprehension — usa un ciclo for
risultati = []
for fattura in fatture:
    if fattura["stato"] == "scaduta":
        giorni = calcola_giorni_ritardo(fattura)
        if giorni > 30:
            fattura["sollecito"] = True
            risultati.append(fattura)
            print(f"Sollecito inviato: {fattura['numero']}")

Se l'operazione ha effetti collaterali (scrivere su file, inviare email, modificare l'oggetto originale), usa un ciclo for normale. La regola pratica: se la comprehension non sta comodamente su una o due righe, probabilmente è meglio un ciclo.

Da ricordare

  • La sintassi base è [espressione for elemento in lista if condizione] — filtra e trasforma in un colpo
  • Usa le comprehension per operazioni semplici: filtrare fatture, formattare importi, generare righe CSV
  • Dict comprehension ({k: v for ...}) e set comprehension ({x for ...}) seguono la stessa logica
  • Se la logica diventa complessa o ci sono effetti collaterali, torna al ciclo for esplicito
  • Le comprehension sono leggermente più veloci dei cicli equivalenti perché ottimizzate internamente da Python