Python tiene algunas cosas muy, pero que muy curiosas, como es, en este caso, la igualación de dos listas.
Supongamos que creamos el siguiente código:
a = [1,2,3]
b=a
print(a)
print(b)
Resultado:
[1, 2, 3, 4]
[1, 2, 3, 4]
Vamos, que vemos el mismo contenido…
Podríamos pensar que toda la lista a se ha copiado en una nueva llamado en b y…aunque a bote pronto lo parezca, no lo es realmente…
Añadamos un elemento a la lista a, por ejemplo, el número 4:
a.append(4)
Ahora, vamos a ver que podemos ver en a y b
print(a)
print(b)
Resultado:
[1, 2, 3, 4]
[1, 2, 3, 4]
…vaya por dios… el cambio que he hecho en a parece haberse propagado a b … umh…
Pues no, no es que se haya propagado, es que b, realmente está apuntando a a … para los que vengan del mundo del lenguaje de programación C, diríamos que b es un puntero a a … de modo que b es simplemente, por decirlo de algún modo, un agujerillo por que el que podemos ver el contenido de a
En resumen, que el obteto lista b es simplemente una referencia al objeto a
Esto, que para algunas cosas puede venir genial, para otras puede ser un auténtico desastre, en caso de que queramos que ambos objetos tenga una vida independiente.
Para poder conseguir esa independencia, en lugar de, simplemente, igular a y b con el clásico a=b, lo que vamos a hacer es volcar el contenido de la lista a en la lista b
Podemos hacerlo de varias formas, incluso de una absurda, que sería recorrer el contenido de la lista e ir añadiéndolo a la lista b mediante un bucle…pero, ya te digo, es absurdo… vamos a hacerlo de forma más rápida:
b=a[:] –> es decir, volcamos todo el contenido de a (no indicamos ni principio ni fin, por lo que lo cogerá todo) a la variable b que automáticamente se convierte en una lista al estar volcándole, precisamente, los elementos de una lista (Python es muy listo…)
a.pop() –> para probar cómo ha quedado, quitamos (sacamos) el último elemento de la lista a y, seguidamente, volvemos a imprimir el contenido de ambas listas:
print(a)
print(b)
Resultado:
[1, 2, 3]
[1, 2, 3, 4]
Y vemos, que efectivamente, a la lista a le falta el último número (que hemos sacado con pop) y que la lista b, ni se ha enterado.
Corolario… ¿existen los punteros en Python?… en este caso, si quitamos la palabra puntero, queda más claro, llamándola simplemente referencia.
Con b=a creamos un objeto b fantasma que siempre referenciará a a y será testigo y reflejo del estado de a
Si volvamos el contenido de a en b con, por ejemplo, b=a[:] , ambas listas serán independientes.