2011-06-15 7 views
1

Duplicate possible:
Python list problemmatrice Initialiser en python

J'essaie d'initialiser une matrice en python. D'abord, je l'ai fait:

>>> M=[[0]*4]*4 

Mais voici mon Probleme, chaque ligne change quand je change le premier:

>>> M 
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 
>>> M[1][1]=1 
>>> M 
[[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0]] 

donc je l'ai fait de cette façon:

>>> M= [ [ 0 for i in range(4) ] for j in range(4) ] 

Et ut fonctionne très bien:

>>> M 
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 
>>> M[1][1]=1 
>>> M 
[[0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 

Ma question est:

Qu'est-ce que ces deux expressions signifient vraiment? et pourquoi le premier se comporte ainsi?

Merci d'avance pour votre aide.

Répondre

1

Dites a est un objet python. Alors [a] * 4 est équivalent à [a, a, a, a]. Cela dépend si a est mutable ou non. Les nombres, les chaînes et les tuples ne le sont pas, donc si a est un de ces types d'objets (0 dans votre exemple), alors vous obtenez 4 copies modifiables indépendamment. Les listes, les dictionnaires et les ensembles sont mutables, et dans ce cas vous obtenez juste 4 références au même objet, dans votre cas la liste [0] * 4. Exploitant cette connaissance, vous verrez que vous pouvez faire ceci:

M = [[0] * 4 for i in range(4)] 

et obtenez ce que vous voulez.

2

Parce qu'ici M=[[0]*4]*4 Vous créez des liens sur des objets.

Il est le même que

>>> a = [0, 0, 0] 
>>> b = [a,a,a] 
>>> b 
[[0, 0, 0], [0, 0, 0], [0, 0, 0]] 
>>> a[1] = 1 
>>> b 
[[0, 1, 0], [0, 1, 0], [0, 1, 0]] 
>>> 

UPD liens que je voulais dire les références, désolé si peu confus

3

Lorsque vous multipliez ces listes, Python est de les copier par référence plutôt que de créer entièrement de nouveaux objets.

Un exemple simple pourrait aider, montrer ce qui se passe avec copie par référence:

>>> pie = ['apple', 'cherry', 'pecan'] 
>>> pie_copy = pie 
>>> pie_copy[0] = 'banana' 
>>> pie 
['banana', 'cherry', 'pecan'] 
>>> pie is pie_copy 
True 
>>> new_pie = ['banana', 'cherry', 'pecan'] 
>>> pie is new_pie 
False 

De la même manière que pie_copy et point de tarte à la même liste, lors de la construction des listes en multipliant, toutes les copies pointent vers la même liste.

Dans votre deuxième extrait utilisant range() et les listes de compréhension, vous ne prenez pas une seule liste et vous la copiez plusieurs fois; chaque itération dans la compréhension crée une nouvelle liste, donc vous ne souffrez pas du même problème de copie par référence.