In Python, le liste (list) sono strutture mutabili, mentre le tuple (tuple) sono immutabili.
Esempio che illustra la modifica di list e tuple:
lst = [1, 2, 3] lst.append(4) # OK lst[1] = 20 # OK tup = (1, 2, 3) tup[1] = 20 # TypeError
Prestazioni:
Domanda: Perché le operazioni di aggiunta di elementi a una lista vengono generalmente eseguite rapidamente (O(1)), se dal punto di vista dell'array dovrebbero portare a una riallocazione della memoria?
Risposta:
Python implementa array dinamici con "allocazione di memoria in eccesso" subito per più elementi. Pertanto, append di solito richiede O(1) e la riallocazione della memoria avviene solo al reale esaurimento del blocco di riserva.
Esempio:
import sys lst = [] for i in range(10): lst.append(i) print(len(lst), sys.getsizeof(lst)) # La dimensione della memoria cresce non in modo rigorosamente lineare
Storia
In un progetto, per le chiavi del dizionario sono state utilizzate list. Lo sviluppatore non sapeva che le liste non sono hashabili (mutabilità), il che ha causato l'errore "TypeError: tipo non hashabile: 'list'".
Lo sviluppatore creava spesso lunghe liste concatenandole tramite +. Questo portava a ulteriori copie dell'array e a costi elevati in termini di memoria e tempo. Era più efficiente utilizzare append in un ciclo o generatori.
Nel sistema di logging, per memorizzare i timestamp sono state scelte tuple, pensando che grazie a immutabilità sarebbe stato più veloce. Ma periodicamente si presenta la necessità di modifiche, il che richiedeva di creare continuamente nuove tuple (copy-on-write) e portava a un rallentamento rispetto all'uso di liste.