Ca fait un petit moment que je me bats avec mes listes, en Python... Dans l'exemple donné sur la photo, je ne comprends pas pourquoi la liste 2 "autre_liste" change de valeur entre la ligne 6 (surlignée) et 7 de la console... Un vrai casse-tête !!
# -*-coding:Latin-1 -*
inventaire = [("pommes", 22), \
("melons", 4), \
("poires", 18), \
("fraises", 76), \
("prunes", 51)]
liste = []
autre_liste = []
for i in inventaire:
liste.clear()
for j in i:
liste.append(j)
print("""liste 2 : {}""".format(autre_liste))
print("""liste 2 : {}""".format(autre_liste))
print("""liste 1 : {}""".format(liste))
autre_liste.append(liste)
print("""liste 2 : {}""".format(autre_liste))
Yup, désolé ^^' !
Après quelques essaies supplémentaires :
# -*-coding:Latin-1 -*
inventaire = [("pommes", 22), \
("melons", 4), \
("poires", 18), \
("fraises", 76), \
("prunes", 51)]
liste = []
autre_liste = []
for i in inventaire:
print("""--> liste 2 : {}""".format(autre_liste))
liste.clear()
print("""0 liste 2 : {}""".format(autre_liste))
for j in i:
liste.append(j)
print("""liste 2 : {}""".format(autre_liste))
print("""liste 2 : {}""".format(autre_liste))
print("""LISTE 1 : {}""".format(liste))
autre_liste.append(liste)
print("""liste 2 : {}""".format(autre_liste))
#~ print(autre_liste)
Le résultat :
"autre_liste" change de valeur au moment de liste.clear() (ligne 13), et je ne comprends vraiment pas pourquoi...
NB : Ce que je voulais faire fonctionne en remplaçant liste.clear() par liste = [], mais je comprends pas pourquoi liste.clear n'a pas le même effet que liste = [], et surtout pourquoi liste.clear modifie autre_liste !
C'est une question de variable muable/immuable et d'étiquette. Pour faire simple, quand tu fais à la ligne 21:
autre_liste.append(liste)
tu ne fais qu'ajouter une nouvelle référence à ta variable liste. Autrement dit, liste et autre_liste[0] référence le même objet. Donc quand tu réinitialises ta liste avec la méthode clear, tu réinitialises aussi autre_liste[0] (car encore une fois les deux pointent vers le même objet). In fine, liste, autre_liste[0], autre_liste[1], autre_liste[2], ... vont référencé le même objet car clear efface toujours le même.
C'est légèrement différent quand tu fais liste = []. L'objet liste et autre_liste[0] référenceront bien le même objet, mais comme tu fais une réaffectation à chaque tour (le liste = []), cette "égalité" n'existera que pour le tour en cours. Donc les éléments de autre_liste ne référenceront pas le même objet: autre_liste[0] sera différent de autre_liste[1] qui sera différent de autre_liste[2], etc ...
Pour illustrer:
autre_lst = []
lst = [1, 2, 3]
autre_lst.append(lst)
autre_lst.append(lst)
autre_lst.append(lst)
print(lst)
print(autre_lst)
#Modification
lst.append(4)
#Le changement s'effectue pour tous
print(lst)
print(autre_lst)
#Par contre si je réaffecte liste à chaque étape
autre_lst = []
lst = [1, 2, 3]
autre_lst.append(lst)
lst = [1, 2, 3]
autre_lst.append(lst)
lst = [1, 2, 3]
autre_lst.append(lst)
print(lst)
print(autre_lst)
#Modification
lst.append(4)
#Seule la dernière est affecté (car elle référence le même objet)
print(lst)
print(autre_lst)
Pas sûr que mon explication soit claire mais si tu veux approfondir, il faut utiliser les mots-clés: étiquette, variable muable/immuable et passage par référence
Hmm... Astucieux ! Je me doutais bien d'un truc dans ce genre là !
Merci beaucoup d'avoir passé du temps à m'expliquer ça !
- Edité par X260 28 février 2016 à 18:47:07
Mon Twitter : @X260_
Liste qui change toute seule
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.