Python e le liste: come usare slicing, copie e sottoliste in modo efficace

by theArchitect
SHARE
Python e le liste: come usare slicing, copie e sottoliste in modo efficace
© Guida-HTML5.it

Introduzione

Le liste sono una delle strutture dati più usate in Python: flessibili, ordinate, modificabili e adatte a moltissimi scenari reali. Quando si lavora con dati raccolti da file, API, form utente o calcoli interni, prima o poi si ha bisogno di estrarre una parte della lista, creare una copia indipendente oppure gestire sottoliste per elaborazioni intermedie.

Questo sotto-argomento è molto pratico perché lo slicing e la copia delle liste sono concetti semplici solo in apparenza: un uso non corretto può introdurre bug difficili da individuare, soprattutto quando si lavora con strutture annidate o con codice che modifica i dati in-place.

In questo tutorial vedremo come:

  • estrarre porzioni di lista con lo slicing;
  • capire la differenza tra copia superficiale e riferimento alla stessa lista;
  • gestire sottoliste in modo sicuro;
  • evitare errori comuni quando si lavora con liste annidate.

Codice completo

# Esempio pratico: gestione di una lista di ordini e delle sue sottoliste

# Lista principale: ogni ordine è rappresentato da una lista annidata
ordini = [
    ["A001", "Alice", 120.50, "spedito"],
    ["A002", "Marco", 89.90, "in elaborazione"],
    ["A003", "Giulia", 45.00, "spedito"],
    ["A004", "Sara", 210.00, "annullato"],
    ["A005", "Luca", 75.25, "in elaborazione"],
]

# 1) Slicing: estrarre i primi tre ordini
primi_tre = ordini[:3]

# 2) Estrarre gli ordini dal secondo al quarto incluso
sottoinsieme = ordini[1:4]

# 3) Copia superficiale della lista principale
copia_ordini = ordini[:]

# 4) Modifica di un elemento nella copia superficiale
copia_ordini[0][3] = "confermato"

# 5) Creare una copia profonda "manuale" delle sottoliste
#    (utile qui perché le liste interne sono oggetti mutabili)
copia_indipendente = [ordine[:] for ordine in ordini]

# 6) Modifica sulla copia indipendente
copia_indipendente[1][3] = "spedito"

# 7) Esempio di slicing con passo
ordini_alternati = ordini[::2]

# 8) Stampa dei risultati
print("Lista originale:")
for ordine in ordini:
    print(ordine)

print("nPrimi tre ordini:")
for ordine in primi_tre:
    print(ordine)

print("nSottoinsieme dal secondo al quarto:")
for ordine in sottoinsieme:
    print(ordine)

print("nCopia superficiale:")
for ordine in copia_ordini:
    print(ordine)

print("nCopia indipendente:")
for ordine in copia_indipendente:
    print(ordine)

print("nOrdini alternati:")
for ordine in ordini_alternati:
    print(ordine)

Spiegazione

Lo slicing è una tecnica che permette di ottenere una porzione di lista usando la sintassi lista[start:stop:step].

1. Estrarre una porzione della lista

Nel codice:

  • ordini[:3] prende i primi tre elementi;
  • ordini[1:4] prende gli elementi dall’indice 1 all’indice 3, perché lo stop è escluso;
  • ordini[::2] prende un elemento sì e uno no, usando un passo pari a 2.

Questo è utile, ad esempio, per analizzare solo una parte dei dati, creare pagine di risultati o fare test su un campione limitato.

2. Copia superficiale: attenzione agli oggetti annidati

Quando scriviamo copia_ordini = ordini[:], otteniamo una nuova lista esterna, ma gli elementi interni restano gli stessi oggetti in memoria. Nel nostro esempio, ogni ordine è a sua volta una lista. Questo significa che modificare copia_ordini[0][3] cambia anche la lista originale.

Questo comportamento sorprende spesso chi inizia. La lista esterna è copiata, ma le liste interne no. Si parla infatti di copia superficiale.

3. Copia indipendente delle sottoliste

Per rendere indipendenti anche le liste interne, abbiamo usato:

  • [ordine[:] for ordine in ordini]

Questa tecnica crea una nuova lista esterna e, per ogni sottolista, ne crea una copia separata. In questo modo, modificare copia_indipendente non altera ordini.

È una soluzione molto utile quando si lavora con dati annidati semplici. In alternativa, per strutture più complesse, si può usare il modulo copy con deepcopy, ma qui ci concentriamo su un approccio chiaro e diretto basato sulle liste.

4. Perché questo argomento è importante nella pratica

Immagina di ricevere una lista di record da elaborare. Potresti voler:

  • mostrare solo una finestra di dati all’utente;
  • fare una copia temporanea per testare una trasformazione;
  • lavorare su una sottoselezione senza rovinare i dati originali;
  • creare snapshot di stato durante un processo di analisi.

In tutti questi casi, capire bene slicing e copie evita bug come modifiche involontarie, risultati incoerenti e difficoltà nel debugging.

Best practice

  • Usa lo slicing quando vuoi una porzione della lista: è leggibile, veloce e idiomatico in Python.
  • Ricorda che lo slicing crea una nuova lista esterna, ma non duplica automaticamente gli oggetti contenuti se sono mutabili.
  • Se gli elementi sono liste o dizionari annidati, verifica se ti serve una copia indipendente.
  • Evita di modificare una lista mentre la stai iterando se non hai una strategia chiara: spesso è meglio lavorare su una copia o su una sottolista.
  • Preferisci nomi espliciti come sottoinsieme, copia_temporanea o campione per rendere il codice più leggibile.
  • Usa lo slicing con passo solo quando il significato è immediato: [::2] è utile, ma non sempre autoesplicativo per chi legge il codice.

Riepilogo

Le liste in Python non servono solo a contenere dati: sono anche uno strumento potente per estrarre, copiare e riorganizzare informazioni in modo efficiente. In questo tutorial abbiamo visto che:

  • lo slicing permette di ottenere sottoliste in modo semplice;
  • una copia superficiale non basta se gli elementi interni sono mutabili;
  • per liste annidate spesso serve creare una copia indipendente degli elementi interni;
  • capire la differenza tra riferimento, copia superficiale e copia indipendente è fondamentale per scrivere codice affidabile.

Se lavori spesso con dati strutturati, padroneggiare questi concetti ti aiuterà a evitare errori sottili e a scrivere programmi più puliti e prevedibili.

Approfondisci con risorse ufficiali

SHARE