La lista 2D tiene un comportamiento extraño al intentar modificar un solo valor [duplicar]


Posible Duplicado:
Característica inesperada en una lista de listas de Python

Así que soy relativamente nuevo en Python y estoy teniendo problemas para trabajar con Listas 2D.

Aquí está mi código:

data = [[None]*5]*5
data[0][0] = 'Cell A1'
print data

Y aquí está la salida (formateada para facilitar la lectura):

[['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None]]

¿Por qué a cada fila se le asigna el valor?

Author: zeet, 2010-04-29

3 answers

Esto hace una lista con cinco referencias a la misma lista:

data = [[None]*5]*5

Use algo como esto en su lugar que crea cinco listas separadas:

>>> data = [[None]*5 for _ in range(5)]

Ahora hace lo que esperas:

>>> data[0][0] = 'Cell A1'
>>> print data
[['Cell A1', None, None, None, None],
 [None, None, None, None, None],
 [None, None, None, None, None],
 [None, None, None, None, None],
 [None, None, None, None, None]]
 54
Author: Mark Byers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-29 17:49:49

Como la referencia de la biblioteca de python para los tipos de secuencia , que incluye listas, dice

Tenga en cuenta también que las copias son poco profundas; las estructuras anidadas no se copian. Esto a menudo atormenta a los nuevos programadores de Python; considere:

>>> lists = [[]] * 3
>>> lists
  [[], [], []]
>>> lists[0].append(3)
>>> lists
  [[3], [3], [3]]

Lo que ha sucedido es que [[]] es una lista de un solo elemento que contiene una lista vacía, por lo que los tres elementos de [[]] * 3 son (punteros a) esta lista vacía única. Modificar cualquiera de los elementos de las listas modifica esta lista única.

Puede crear una lista de diferentes listas de esta manera:

>>> lists = [[] for i in range(3)]  
>>> lists[0].append(3)
>>> lists[1].append(5)
>>> lists[2].append(7)
>>> lists
  [[3], [5], [7]]
 10
Author: Mark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-26 22:32:45

En python cada variable es un objeto, y por lo tanto una referencia. Primero creaste una matriz de 5 Nones, y luego construyes una matriz con 5 veces el mismo objeto.

 2
Author: lfagundes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-29 17:51:32