[Python-es] Problema con listas duplicadas

Francesc Gispert Sanchez francesc_gispert_11.12 en hotmail.com
Vie Ago 5 13:10:02 CEST 2011


Hola de nuevo, muchas gracias por vuestros comentarios, pero sigue
modificándose el tablero principal de mi juego. 

El vie, 05-08-2011 a las 08:53 +0100, Luis Garcia Merino escribió:
> Buenos días,
> para duplicar el tablero original puedes utilizar deepcopy del módulo
> copy:
> 
> http://www.python.org/doc//current/library/copy.html
> 
> Un saludo,
> 
>        Luis

He sustituido el contenido de la función
'duplicaTauler' (duplicaTablero) con una llamada a deepcopy con el
tablero principal como argumento, que es lo que entendí que sugeriste,
pero al modificar el tablero provisional, el principal también se
modifica. Y la verdad es que no lo comprendo, porque en la interfaz
interactiva de Python me funciona de la forma que yo espero.

El vie, 05-08-2011 a las 09:54 +0200, Eduard Diaz escribió:
> Hola,
> 
> Para este tipo de problemas lo mejor es usa la interfaz interactiva de
> python en consola
> 
> Ejemplo de funcionamiento de la copia de listas:
> 
> Creamos una lista tipo tauler:
> >>> a = [[y for y in range(4)] for x in range(4)]
> >>> a
> [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
> 
> Creamos una referencia:
> >>> b = a 
> 
> Comprobamos que si modificamos uno y se modifica en el otro
> 
> >>> a[0][1]= 5 
> >>> a
> [[0, 5, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
> >>> b
> [[0, 5, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
> 
> Si copiamos la lista:
> >>> b=a[:]
> 
> Si modificamos un valor de la sublista vemos que tambien se modifica
> en la sublista copia
> >>> b[0][1]= 8  
> >>> a
> [[0, 8, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
> >>> b
> [[0, 8, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
> 
> Pero si añadimos un elemento mas en la lista principal, no se copia!
> >>> b.append([x for x in range(4)])
> >>> b
> [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
> >>> a
> [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
> 
> Esto es porque si entendemos que el tauler (a) es una lista de listas
> se entiende mas
> facilmente que hay que duplicar los dos niveles, la lista y la
> sublista
> 
> Duplicamos:
> >>> b = [x[:] for x in a]
> >>> b
> [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
> >>> a
> [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
> 
> Modificamos:
> >>> b[0][1]= 7
> >>> b
> [[0, 7, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
> >>> a
> [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
> 
> Espero que te sea de ayuda
> 
> Un saludo
> 
> Eduard Diaz

Muchas gracias por tu explicación, es muy completa. Efectivamente, si
ejecuto todo esto en la interfaz interactiva de Python, el resultado es
el esperado. Sin embargo, de la misma forma que la propuesta de Luis, no
me funciona cuando sustituyo el contenido de la función para duplicar el
tablero por algo parecido a:

def duplicaTablero(tablero):
    return [x[:] for x in tablero]

El contenido del tablero sigue cambiando en cada llamada a la función
'giraFitxes' (giraFichas). Por un momento he pensado que tal vez dentro
de esta función había alguna cosa que modificaba el contenido de la
matriz del tablero principal, pero sólo lo recorre y hace una
comprobación en un 'if'. 

La verdad es que me confunde un poco esto de que el resultado sea
distinto en la interfaz interactiva de Python que cuando ejecuto un
script .py.


Gracias a ambos por vuestras respuestas, pero mi problema persiste.
Intentaré ejecutar el script en otro ordenador, a ver si el resultado es
el mismo, pero no creo que pueda tener nada que ver, ¿no? En todo caso,
seguiré haciendo algunas pruebas, a ver si doy con una solución.


Francesc Gispert




Más información sobre la lista de distribución Python-es