Python: ¿cómo agregar nuevos elementos en una lista de la lista?

Aquí hay un progtwig muy simple:

a = [[]]*3 print str(a) a[0].append(1) a[1].append(2) a[2].append(3) print str(a[0]) print str(a[1]) print str(a[2]) 

Aquí está la salida que esperaba:

  [[], [], []] [1] [2] [3] 

Pero en cambio me sale esto:

  [[], [], []] [1, 2, 3] [1, 2, 3] [1, 2, 3] 

¡Realmente hay algo que no consigo!

Debes hacer

 a = [[] for i in xrange(3)] 

no

 a = [[]]*3 

Ahora funciona:

 $ cat /tmp/3.py a = [[] for i in xrange(3)] print str(a) a[0].append(1) a[1].append(2) a[2].append(3) print str(a[0]) print str(a[1]) print str(a[2]) $ python /tmp/3.py [[], [], []] [1] [2] [3] 

Cuando haces algo como a = [[]]*3 , obtienes la misma lista [] tres veces en una lista. Lo mismo significa que cuando cambias uno de ellos, los cambias a todos (porque solo hay una lista a la que se hace referencia tres veces).

Es necesario crear tres listas independientes para evitar este problema. Y lo haces con una lista de comprensión. Usted construye aquí una lista que consiste en listas vacías independientes [] . Se creará una nueva lista vacía para cada iteración sobre xrange(3) (la diferencia entre range y xrange no es tan importante en este caso; pero xrange es un poco mejor porque no produce la lista completa de números y simplemente devuelve un objeto iterador en su lugar).

El problema fundamental con su enfoque es que cuando multiplica la lista por tres, la lista resultante contiene tres de la misma lista . Así que a[0] , a[1] y a[2] referencia a la misma cosa. Cuando se agrega a cualquiera de estos, se agrega a la misma lista. Esta es la razón por la cual el efecto de sus llamadas a append() parece estar triplicado.

En su lugar, genere su lista de listas sin hacer referencia a la misma lista. Como ejemplo, puede utilizar la comprensión de lista, como tal.

 [[] for i in range(3)] 

Cuando escribes:

 a = [[]]*3 

No hará 3 copias de la lista vacía interna, sino que hará 3 referencias al mismo objeto.

De la misma manera, si lo haces:

 b = [1,2,3] c = b c.append(4) print b 

Usted obtiene como la salida:

 [1, 2, 3, 4] 

Esto se debe a que byc son dos referencias diferentes (puede decir dos nombres diferentes) a la misma lista. Puede cambiar el objeto de cualquier referencia, pero verá los resultados de todos ellos, ya que apuntan a la misma cosa.

Esto le dará una idea clara, ya que todos los objetos tienen el mismo id () y todos son mutables, por lo que editar cualquiera de ellos editará automáticamente otro también, ya que solo son referencias a un mismo objeto con id = 18671936 y en m todos tienen id diferentes (), por lo que todos ellos son objetos diferentes.

 >>> l = [[]]*4 >>> for x in l: print(id(x)) 18671936 18671936 18671936 18671936 >>> m=[[],[],[],[]] >>> for x in m: print(id(x)) 10022256 18671256 18672496 18631696 

Por lo tanto, debe crear su lista como esta:

 >>> a=[[] for _ in range(4)] >>> a[0].append(1) >>> a[2].append(5) >>> a [[1], [], [5], []] 

¡Realmente hay algo que no consigo!

a = [[]]*3 El problema aquí es que está configurando las listas para que sean la misma referencia, ya que las matrices y los diccionarios se almacenan como referencias.

 >>> a = [[]]*3 >>> a[0] is a[1] or a[0] is a[2] True >>> a[0] is a[1] or a[0] is a[2] or a[1] is a[2] True >>> 

lo mismo ocurre si haces a = [{}] * 3`

como tal, debe tener cuidado, puede hacer una lista de comprensión [[] for _ in xrange(3)] o definir estáticamente las 3 de sus matrices [[], [], []] .

 >>> a = [[] for _ in xrange(3)] >>> a[0] is a[1] or a[0] is a[2] or a[1] is a[2] False >>>