Partage
  • Partager sur Facebook
  • Partager sur Twitter

Liste qui change toute seule

Sujet résolu
    28 février 2016 à 13:14:53

    Prise le 28/02/2016, à 13:09:23

    Bonjour à tous !

    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 !!

    Pouvez-vous m'aider ?

    Merci d'avance,

    Cordialement,

    -
    Edité par X260 28 février 2016 à 14:32:17

    • Partager sur Facebook
    • Partager sur Twitter
    Mon Twitter : @X260_
      28 février 2016 à 13:20:34

      Prends 20 secondes pour recopier ton code en utilisant les balises adaptées </> et de choisir le langage python. Merci :-°
      • Partager sur Facebook
      • Partager sur Twitter
      Précepte: Le mieux est l'ennemi du bien
        28 février 2016 à 14:13:44

        # -*-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 :p !

        -
        Edité par X260 28 février 2016 à 14:58:13

        • Partager sur Facebook
        • Partager sur Twitter
        Mon Twitter : @X260_
          28 février 2016 à 15:53:55

          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

          • Partager sur Facebook
          • Partager sur Twitter
          Précepte: Le mieux est l'ennemi du bien
            28 février 2016 à 18:46:21

            Hmm... Astucieux ! Je me doutais bien d'un truc dans ce genre là :p !

            Merci beaucoup d'avoir passé du temps à m'expliquer ça ;) !

            -
            Edité par X260 28 février 2016 à 18:47:07

            • Partager sur Facebook
            • Partager sur Twitter
            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.
            • Editeur
            • Markdown