2015-10-11 1 views
0

Je suis confronté à un problème que je ne peux pas résoudre tout seul maintenant. Son sur l'extrait suivant:Ajouter Liste à Liste en Python

counter = 0 
appendList = [] 
valueList = [[0], [0]] 

for i in range(0,3): 

    valueList[1] = counter 
    print "Loop " , i , " valueList: " , valueList 
    print "Appending (valueList): " , valueList , " to (appendList): " , appendList 
    appendList.append(valueList) 
    counter = counter + 1 


print "Final appendList: " , appendList 

Il en résulte la sortie suivante:

Loop 0 valueList: [[0], 0] 
Appending (valueList): [[0], 0] to (appendList): [] 
Loop 1 valueList: [[0], 1] 
Appending (valueList): [[0], 1] to (appendList): [[[0], 1]] 
Loop 2 valueList: [[0], 2] 
Appending (valueList): [[0], 2] to (appendList): [[[0], 2], [[0], 2]] 
Final appendList: [[[0], 2], [[0], 2], [[0], 2]] 

Je voulais que le Snippet d'ajouter différents List-Items au appendList. Le résultat final devrait ressembler à ceci:

[[[0], 0], [[0], 1], [[0], 2]] 

Mais comme vous pouvez le voir, l'extrait remplit le appendList avec les mêmes valeurs de la plus haute contre.

Quelqu'un peut-il m'expliquer ce comportement ou me dire où est mon erreur?

+0

Affectez une copie à chaque fois, comme ceci 'appendList.append (valueList [:])' – thefourtheye

+0

Merci mon ami, qui a résolu mon problème. Pouvez-vous expliquer pourquoi? – user2058521

+0

Écrire une réponse à ce sujet maintenant. – ppperry

Répondre

2

valueList est le même objet chaque fois que vous l'ajoutez, donc le modifier à un endroit semble le modifier partout

>>> a = [0] 
>>> b = a 
>>> a[0] = 42 
>>> b 
[42] 

Vous devez en ajouter une copie afin d'ajouter une nouvelle liste à chaque fois.

appendList.append(valueList[:]) 
1

Vous pouvez essayer:

counter = 0 
appendList = [] 
valueList = [[0], [0]] 

for i in range(0,3): 

    valueList[1] = counter 
    print "Loop " , i , " valueList: " , valueList 
    print "Appending (valueList): " , valueList , " to (appendList): " , appendList 
    appendList.append(valueList[:]) 
    counter = counter + 1 


print "Final appendList: " , appendList 

Sortie:

Loop 0 valueList: [[0], 0] 
Appending (valueList): [[0], 0] to (appendList): [] 
Loop 1 valueList: [[0], 1] 
Appending (valueList): [[0], 1] to (appendList): [[[0], 0]] 
Loop 2 valueList: [[0], 2] 
Appending (valueList): [[0], 2] to (appendList): [[[0], 0], [[0], 1]] 
Final appendList: [[[0], 0], [[0], 1], [[0], 2]] 

Explication:

Lorsque vous attribuez objet valuelist, tous les éléments sont assignez de l'objet referance. Donc, au lieu de b = a, vous pouvez faire b = a [:] parce que c'est seulement une copie à chaque fois de cet objet.

>>> a = [1, 2, 3] 
>>> b = a 
>>> a[:] = [4, 5, 6] 
>>> b 
[4, 5, 6] 
>>> a 
[4, 5, 6] 
>>> b = a [:] 
>>> a = [1, 2, 3] 
>>> b 
[4, 5, 6] 
>>> a 
[1, 2, 3] 
>>> 
+0

Bien qu'il résout le problème, cela n'explique pas pourquoi et est une copie exacte du commentaire de @ thefourtheye. – ppperry

+0

Ok, attendez. J'écris l'explication –

+0

@ppperry: Maintenant c'est ok? –

0

appendList contient une référence à la valeur actuelle de valueList, donc lorsque vous modifiez valueList, les copies en appendList changement. Vous devez créer une copie de valueList chaque fois que vous y mettez appendList.

0

valueList pointe toujours vers un seul objet. Vous pouvez vérifier cela en imprimant le id(valueList). id donne identité de l'objet. c'est-à-dire l'adresse mémoire de l'objet. Dans votre exemple, si vous imprimez l'identifiant, il sera toujours le même.

counter = 0 
appendList = [] 
valueList = [[0], [0]] 

for i in range(0,3): 
    print "id of valueList before", id(valueList) 
    #creates a copy of valueList. 
    valueList = valueList[:] 
    print "id of valueList after", id(valueList) 
    valueList[1] = counter 
    print "Loop " , i , " valueList: " , valueList 
    print "Appending (valueList): " , valueList , " to (appendList): ", appendList 
    appendList.append(valueList) 
    counter = counter + 1 


print "Final appendList: " , appendList 
0
counter = 0 
appendList = [] 
valueList = [[0], [0]] 

print(valueList[1][0]) 

for i in range(0,3): 

    print(counter) 
    valueList[1][0] = counter # this was wrong 
    print ("Loop " , i , " valueList: " , valueList) 
    print ("Appending (valueList): " , valueList , " to (appendList): " , appendList) 
    appendList.append(valueList) 
    valueList = [[0], [0]] # and this was absent 
    counter += 1 

print(appendList) 

[[[0], [0]], [[0], [1]], [[0], [2]]] 
0

Une bonne habitude est aussi de vérifier l'efficacité de votre code plus tard: vous définissez plusieurs variables tout (pour moi) vous êtes intéressé par appendList.

appendList = [ [[0], x] for x in range(3) ] # doStuff for index in range of n print appendList Avec la compréhension de la liste, vous pouvez réduire seulement le calcul nécessaire.