Python

Problemas con listas mutables en Python: Cómo evitar efectos inesperados

Las listas en Python son estructuras de datos mutables, lo que significa que su contenido puede modificarse después de su creación. Esta característica las diferencia de las tuplas, que son inmutables y no permiten cambios una vez definidas. Mientras que la mutabilidad de las listas ofrece gran flexibilidad, también puede generar efectos inesperados si no se gestionan de forma adecuada. Problemas como modificaciones no deseadas, referencias compartidas y errores en las funciones que reciben listas como argumentos son comunes al trabajar con listas mutables.

En esta entrada, abordaremos algunos de los errores más frecuentes que pueden aparecer al trabajar con listas mutables en Python y explicaremos cómo evitarlos para lograr un código más robusto, predecible y fácil de mantener.

¿Qué son las listas mutables en Python?

En Python, los objetos pueden ser mutables o inmutables:

  • Mutables: Son aquellos cuyo contenido puede modificarse después de su creación. Ejemplos: listas, diccionarios, conjuntos.
  • Inmutables: Son aquellos cuyo contenido no puede modificarse después de su creación. Ejemplos: tuplas, cadenas de texto, números (enteros, flotantes).
mi_lista = [1, 2, 3]
mi_lista.append(4)  # Modificamos la lista original

print(mi_lista)
[1, 2, 3, 4]

Problemas comunes al trabajar con listas mutables

Aquí te mostramos algunos de los errores más comunes y cómo evitarlos para que tu código sea más seguro y fácil de mantener.

Modificación inesperada al asignar listas

En Python, cuando asignas una lista a otra variable, ambas referencias apuntan al mismo objeto en memoria. Es decir, hay una única lista en memoria con dos nombres. Esto puede llevar a modificaciones no deseadas si una de las listas es modificada.

lista_a = [1, 2, 3]
lista_b = lista_a  # Ambas variables apuntan a la misma lista

lista_b.append(4)  # Modificamos lista_b
print(lista_a)  # La lista_a también cambió
[1, 2, 3, 4]

Solución: Para evitar este comportamiento, utiliza métodos como copy() o deepcopy() para crear copias independientes de la lista:

lista_a = [1, 2, 3]
lista_b = lista_a.copy()  # Ahora lista_b es una copia independiente

lista_b.append(4)
print(lista_a)  # [1, 2, 3] (No se modifica)
print(lista_b)  # [1, 2, 3, 4]
[1, 2, 3]
[1, 2, 3, 4]

Si la lista contiene elementos mutables, como sublistas, es recomendable usar deepcopy():

import copy

lista_anidada = [[1, 2], [3, 4]]
copia_profunda = copy.deepcopy(lista_anidada)

Mutabilidad en funciones: Modificaciones no deseadas

Cuando pasamos una lista como argumento a una función, esta puede modificarse dentro de la función, lo cual puede producir efectos indeseados si no se toma precaución.

def agregar_elemento(lista):
    lista.append(100)  # Modifica la lista original


mi_lista = [1, 2, 3]
agregar_elemento(mi_lista)
print(mi_lista)  # Se modificó inesperadamente
[1, 2, 3, 100]

Solución: Para evitar este problema, haz una copia de la lista dentro de la función antes de modificarla:

def agregar_elemento(lista):
    lista_copia = lista.copy()  # Copia de la lista
    lista_copia.append(100)
    return lista_copia


mi_lista = [1, 2, 3]
nueva_lista = agregar_elemento(mi_lista)
print(mi_lista)     # No cambia
print(nueva_lista)  # Nueva lista con un elemento
[1, 2, 3]
[1, 2, 3, 100]

Problemas con valores predeterminados mutables en funciones

Una de las trampas más sutiles en Python ocurre cuando usas una lista mutable como valor predeterminado de un parámetro de función. En este caso, todas las llamadas sucesivas compartirán la misma lista.

def agregar_valor(valor, lista=[]):
    lista.append(valor)
    return lista


print(agregar_valor(1))  # [1]
print(agregar_valor(2))  # [1, 2] (Acumula valores inesperadamente)
print(agregar_valor(3))  # [1, 2, 3]
[1]
[1, 2]
[1, 2, 3]

Solución: Una forma de evitar este comportamiento es usar None como valor predeterminado y crear una nueva lista dentro de la función:

def agregar_valor(valor, lista=None):
    if lista is None:
        lista = []  # Se crea una nueva lista en cada llamada
    lista.append(valor)
    return lista


print(agregar_valor(1))  # [1]
print(agregar_valor(2))  # [2] (Ya no acumula valores inesperados)
[1]
[2]

Mutabilidad en estructuras anidadas

Si una lista mutable contiene otras listas, cambiar una sublista afectará todas las referencias a esa sublista. Este problema puede ser difícil de detectar si no se presta atención.

matriz = [[0] * 3] * 3  # Crea 3 referencias al mismo objeto
matriz[0][0] = 1

print(matriz) # Todas las filas cambiaron
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]

Solución: Usa comprensión de listas para crear copias independientes de cada sublista:

matriz = [[0] * 3 for _ in range(3)]  # Cada fila es una lista independiente
matriz[0][0] = 1

print(matriz)
[[1, 0, 0], [0, 0, 0], [0, 0, 0]]

Conclusiones

Las listas mutables en Python son una herramienta poderosa y flexible, pero pueden llevar a errores difíciles de detectar si no se manejan adecuadamente. Siguiendo las buenas prácticas aquí descritas, puedes evitar problemas comunes como referencias compartidas, modificaciones no deseadas y errores complicados en funciones. Asegúrate de crear copias adecuadas cuando sea necesario y ten en cuenta la mutabilidad de las estructuras de datos para escribir un código más predecible y fácil de depurar.

Nota: La imagen de este artículo fue generada utilizando un modelo de inteligencia artificial.

¿Te ha parecido de utilidad el contenido?

Daniel Rodríguez

Share
Published by
Daniel Rodríguez

Recent Posts

Curiosidad: ¿Por qué usamos p < 0.05? Un umbral que cambió la historia de la ciencia

En casi cualquier análisis estadístico —ya sea en medicina, psicología, economía o ciencia de datos—…

3 días ago

¿Está concentrado el MSCI World? Un análisis con Gini, Lorenz y leyes de potencia

El MSCI World Index suele presentarse como “la ventana al mundo” para quienes invierten en…

5 días ago

Curiosidad: La maldición de la dimensionalidad, o por qué añadir más datos puede empeorar tu modelo

En el mundo del análisis de datos solemos escuchar una idea poderosa: cuantos más datos,…

1 semana ago

Error npm ERR! code EACCES al instalar paquetes en Node.js: Cómo solucionarlo paso a paso

¿Te has encontrado con este error al intentar instalar paquetes con npm? npm ERR! code…

2 semanas ago

Curiosidad: La Paradoja de Simpson, o por qué no siempre debes fiarte de los promedios

En ciencia de datos y estadística, los promedios y porcentajes son herramientas fundamentales para resumir…

2 semanas ago

Copias de seguridad automáticas en SQL Server con rotación de archivos

Las bases de datos son el corazón de casi cualquier sistema de información moderno. Ya…

3 semanas ago

This website uses cookies.