En Python, las listas (list) son estructuras mutables, mientras que las tuplas (tuple) son inmutables.
Ejemplo que ilustra el cambio en list y tuple:
lst = [1, 2, 3] lst.append(4) # OK lst[1] = 20 # OK tup = (1, 2, 3) tup[1] = 20 # TypeError
Rendimiento:
Pregunta: ¿Por qué las operaciones de agregar elementos a una lista suelen ser rápidas (O(1)), si desde el punto de vista de un arreglo deberían llevar a la redistribución de memoria?
Respuesta:
Python implementa arreglos dinámicos "con reserva de memoria" de inmediato para varios elementos. Por lo tanto, append generalmente toma O(1), y la redistribución de memoria ocurre solo cuando el bloque reservado se agota realmente.
Ejemplo:
import sys lst = [] for i in range(10): lst.append(i) print(len(lst), sys.getsizeof(lst)) # El tamaño de la memoria no crece de forma estrictamente lineal
Historia
En un proyecto, se usaron list para las claves de un diccionario. El desarrollador no sabía que las listas no se pueden hashear (mutabilidad), lo que provocó el error "TypeError: unhashable type: 'list'".
El desarrollador a menudo creaba listas largas concatenándolas a través de +. Esto resultaba en copias adicionales del arreglo y altos costos de memoria y tiempo. Era más eficiente usar append en un ciclo o generadores.
En el sistema de registro, se eligieron tuplas para almacenar marcas de tiempo, pensando que por ser inmutables sería más rápido. Pero de vez en cuando surgía la necesidad de modificarlas, lo que requería crear nuevas tuplas constantemente (copy-on-write) y llevaba a una disminución del rendimiento en comparación con el uso de listas.