868 votes

Liste de Python de listes, change de sous-listes réfléchies à travers inopinément

J’avais besoin de créer une liste de listes en Python, alors j’ai tapé le texte suivant :

La liste ressemblée à ceci :

Puis j’ai changé une des valeurs plus intimes :

Maintenant ma liste ressemble à ceci :

qui n’est pas ce que j’ai voulu ou prévu. Quelqu'un peut-il expliquer s’il vous plaît ce qui se passe et comment le contourner ?

741voto

CAdaker Points 3947

Quand vous écrivez [x]*3 vous obtenez essentiellement la liste [x, x, x] . C'est-à-dire, une liste avec 3 références à x . Lorsque vous modifiez ensuite x les trois références sont modifiées.

Pour le réparer, vous devez vous assurer que vous créez une nouvelle liste à chaque position. Une façon de le faire est

 [[1]*4 for n in range(3)]
 

166voto

nadrimajstor Points 81
size = 3
matrix_surprise = [[0] * size] * size
matrix = [[0]*size for i in range(size)]

Frames and Objects

Vivre Python Tutor Visualiser

69voto

PierreBdR Points 11479

En fait, c'est exactement ce que vous attendez. Nous allons décomposer ce qui se passe ici:

Vous écrivez

lst = [[1] * 4] * 3

Ceci est équivalent à:

lst1 = [1]*4
lst = [lst1]*3

Cela signifie lst une liste avec les 3 éléments pointant vers lst1. Cela signifie que les deux lignes suivantes sont équivalentes:

lst[0][0] = 5
lst1[0] = 5

En tant que lst[0] n'est rien, mais lst1.

Pour obtenir le comportement désiré, vous pouvez utiliser la liste de compréhension:

lst = [ [1]*4 for n in xrange(3) ]

Dans ce cas, l'expression est ré-évaluée pour chaque n, conduisant à une liste différente.

46voto

Blair Conrad Points 56195
  [[1] * 4] * 3
 

ou même

  [[1, 1, 1, 1]] * 3
 

Crée une liste qui référence le [1,1,1,1] interne 3 fois - et non trois copies de la liste interne, donc à chaque fois que vous modifiez la liste (dans n'importe quelle position), vous verrez le changement trois fois.

C'est la même chose que cet exemple:

 >>> inner = [1,1,1,1]
>>> outer = [inner]*3
>>> outer
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
>>> inner[0] = 5
>>> outer
[[5, 1, 1, 1], [5, 1, 1, 1], [5, 1, 1, 1]]
 

où c'est probablement un peu moins surprenant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X