web-dev-qa-db-fra.com

La liste 2D a un comportement étrange lors de la tentative de modification d'une seule valeur

Dupliquer possible:
[.____] fonctionnalité inattendue dans A Python Liste des listes

Donc, je suis relativement nouveau à Python et j'ai du mal à travailler avec des listes 2D.

Voici mon code:

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

et voici la sortie (formatée pour la lisibilité):

[['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]]

Pourquoi chaque ligne est-elle attribuée la valeur?

54
Brian

Cela fait une liste avec cinq références à la liste pareil:

data = [[None]*5]*5

Utilisez quelque chose comme ça plutôt que ceci crée cinq listes distinctes:

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

Maintenant, cela fait ce que vous attendez:

>>> 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]]
68
Mark Byers

Comme la référence de la bibliothèque Python pour les types de séquence , qui inclut des listes, dit

Notez également que les copies sont peu profondes; Les structures imbriquées ne sont pas copiées. Cela hante souvent nouveau Python programmeurs; considérez:

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

Ce qui s'est passé est que [[[]] est une liste d'un élément contenant une liste vide, de sorte que les trois éléments de [[]] * 3 sont (pointeurs vers) cette seule liste vide. Modification de l'un des éléments des listes modifie cette liste unique.

Vous pouvez créer une liste de listes différentes de cette façon:

>>> lists = [[] for i in range(3)]  
>>> lists[0].append(3)
>>> lists[1].append(5)
>>> lists[2].append(7)
>>> lists
  [[3], [5], [7]]
14
Mark

IN python Chaque variable est un objet, et donc une référence. Vous avez créé une matrice de 5 non, puis vous construisez une matrice avec 5 fois le même objet.

2
lfagundes