Python copia una lista de listas

Estoy usando python 3.4.1.
Para una lista única a=[1,2] , si hago una copia de ella, b = a.copy() cuando cambio elementos en b , no cambiará elementos en a .
Sin embargo, cuando defino una lista de listas (en realidad una matriz) a = [[1,2],[3,4]] , cuando asigno b = a.copy() . Lo que hago para enumerar b realidad afecta a .
Revisé sus direcciones, son diferentes.
puede alguien decirme por que?

ps: Lo que hice es b[0][0] = x , y el elemento en a también se cambió.

De los documentos para el módulo de copy :

La diferencia entre copia superficial y profunda solo es relevante para objetos compuestos (objetos que contienen otros objetos, como listas o instancias de clase):

  • Una copia superficial construye un nuevo objeto compuesto y luego (en la medida de lo posible) inserta referencias en él a los objetos que se encuentran en el original.
  • Una copia profunda construye un nuevo objeto compuesto y luego, recursivamente, inserta copias en él de los objetos que se encuentran en el original.

Cuando llama a copy.copy() normal está realizando una copia superficial . Esto significa que en el caso de una lista de listas, obtendrá una nueva copia de la lista externa, pero contendrá las listas internas originales como sus elementos. En su lugar, debe usar copy.deepcopy() , que creará una nueva copia de las listas externa e interna.

La razón por la que no notó esto con su primer ejemplo de uso de copy([1,2]) es que las primitivas como int son inmutables y, por lo tanto, es imposible cambiar su valor sin crear una nueva instancia. Si los contenidos de la lista hubieran sido en su lugar objetos mutables (listas similares o cualquier objeto definido por el usuario con miembros mutables), cualquier mutación de esos objetos se habría visto en ambas copias de la lista.

Quizás una lista de comprensión como tal:

 new_list = [x[:] for x in old_list] 

… aunque si sus matrices son más profundas que una capa, la comprensión de la lista es probablemente menos elegante que solo usar una deepcopy .

editar: una copia superficial, como se indica, aún contendrá referencias a los objetos dentro de la lista. Así por ejemplo…

 >>> this = [1, 2] >>> that = [33, 44] >>> stuff = [this, that] >>> other = stuff[:] >>> other [[1, 2], [33, 44]] >>> other[0][0] = False >>> stuff [[False, 2], [33, 44]] #the same problem as before >>> this [False, 2] #original list also changed >>> other = [x[:] for x in stuff] >>> other [[False, 2], [33, 44]] >>> other[0][0] = True >>> other [[True, 2], [33, 44]] >>> stuff [[False, 2], [33, 44]] #copied matrix is different >>> this [False, 2] #original was unchanged by this assignment 

Es muy simple, solo haz eso:

 b = a 

Ejemplo:

 >>> a = [1, 2, 3] >>> b = a >>> b.append(4) >>> b [1, 2, 3, 4] >>> a [1, 2, 3, 4]