2010-04-29 9 views
36

Duplicar posible:
Unexpected feature in a Python list of listslista 2D tiene behavor raro cuando se trata de modificar un solo valor

así que estoy 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 (formato 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é cada fila se asignan el valor?

+4

Oh chico, pero estaba atrapado en este mismo problema en su día .. :) – ktdrv

Respuesta

45

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

data = [[None]*5]*5 

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

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

Ahora se hace lo que se espera:

>>> 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]] 
2

En python cada variable es un ob objeto, y entonces una referencia. Primero creó una matriz de 5 Nones, y luego construye una matriz con 5 veces el mismo objeto.

8

A medida que el python library reference for sequence types, 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; Consideremos:

>>> 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) de este lista única vacía La modificación de cualquiera de los elementos de las listas modifica esta única lista.

Puede crear una lista de las 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]] 
Cuestiones relacionadas