IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Problème de modification de listes égales


Sujet :

Python

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Points : 67
    Points
    67
    Par défaut Problème de modification de listes égales
    Bonsoir,

    Je fais appel à votre sagacité...
    Voilà en effet un comportement des listes que je n'arrive pas à contourner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> L=[1,3,5]
    >>> K = L
    >>> L[1]=7
    >>> print K
    [1, 7, 5]
    1re question
    Ceci ne se produit qu'avec les listes, pourquoi ?
    2e question
    Comment contourner la difficulté ? Je voudrais pouvoir toucher à l'une sans que la modif affecte l'autre...

    Merci d'avance

  2. #2
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    bonsoir,

    par défaut python utilise des références.

    la ligne:

    est traduite par: L pointe vers la même adresse mémoire que K. Du coup, toute modification dans L se répercute dans K et inversement, car cela modifie une adresse mémoire commune.

    Cela ne se produit pas qu'avec des listes .

    pour que les listes soient indépendantes, il faut en quelque sorte faire une "copie". par exemple comme ceci:


  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 222
    Points : 290
    Points
    290
    Par défaut
    Tu peux aussi utiliser:
    qui copie l'intégralité de L dans K

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Points : 67
    Points
    67
    Par défaut
    Bonsoir,

    Merci pour vos réponses...
    Je vais tester ça...
    kango, avec quoi cela se produit-il encore ? Parce que j'avais testé : cela ne produit pas avec les variables numériques :
    >>> a=2
    >>> b=a
    >>> a=3
    >>> print b
    2
    ni avec les chaînes :
    >>> a="bla"
    >>> b=a
    >>> a="bli"
    >>> print b
    bla
    Cordialement,

    @+

  5. #5
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    à ma connaissance avec tout sauf les types standards: str, float, int...

  6. #6
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    723
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 723
    Points : 923
    Points
    923
    Par défaut
    Ça se produit avec tout, y compris les types de base, seulement on ne peut pas s'en rendre compte, étant donné que ces derniers sont en général immuables (mis à part les dicos et les listes), et donc que pour les manipuler, il faut réaffecter. La preuve :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> a = 1
    >>> b = a
    >>> id(a)
    135720760
    >>> id(b)
    135720760
    En Python, tout est objet, et n'importe quelle variable ne contient qu'une référence vers un objet, pouvant être référencé par d'autres variables. Par suite, tout passage d'objet à une fonction ou méthode se fait par référence, et non par valeur. C'est une conséquence du fait que tout est objet, premièrement copier une instance de classe peut être coûteux, deuxièmement ce n'est en général pas le comportement attendu, notamment quand on commence à manipuler des classes un peu plus élaborées.

  7. #7
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    ah oui exact, je m'étais contenté de faire le test:
    et l'id change pour b après l'incrémentation. je pensais que cet opérateur modifiait sur place même pour les int.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 99
    Points : 102
    Points
    102
    Par défaut
    En fait la syntaxe Pyhton à ce propos est très précise.
    • b+=1 est vraiment la compression de b=b+1, ce qui implique qu'on ne modifie pas b mais qu'on assigne à la variable une nouvelle valeur entière.
    • Les syntaxe b++/++b n'existent pas parce qu'elles sous entendent que b est modifié, ce qui n'est pas possible.
    Tout est très logique.

    La notion d'objets mutable / non mutable (que l'on peut presque assimilé à non constant / constant) est vraiment un de concepts fondamental du Python.
    Je vous conseil d'être vraiment au point la dessus si vous commencez à écrire du code parce que cela peut donner des bugs vraiment pas simple a identifier et à corriger.


    De la même façon voici un des autres pièges assez spécifique au Python qui utilise aussi une liste et qu'il convient de connaitre et comprendre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    def fct_append(valeur, liste=[]):
        liste.append(valeur)
        return liste
     
    l = [1, 2]
    print fct_append(3, l)
    print fct_append(4)
    print fct_append(5)

  9. #9
    Membre confirmé Avatar de dapounet
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2007
    Messages
    469
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2007
    Messages : 469
    Points : 567
    Points
    567
    Par défaut
    Bonjour,

    Citation Envoyé par shadowsam Voir le message
    • b+=1 est vraiment la compression de b=b+1, ce qui implique qu'on ne modifie pas b mais qu'on assigne à la variable une nouvelle valeur entière.
    Non, += fait une modification in-place quand c'est possible.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> a = [1, 2, 3]
    >>> b = a
    >>> a += [4]
    >>> a, b
    ([1, 2, 3, 4], [1, 2, 3, 4])
    An augmented assignment expression like x += 1 can be rewritten as x = x + 1 to achieve a similar, but not exactly equal effect. In the augmented version, x is only evaluated once. Also, when possible, the actual operation is performed in-place, meaning that rather than creating a new object and assigning that to the target, the old object is modified instead.
    http://docs.python.org/reference/sim...ent-statements
    :wq

  10. #10
    Membre confirmé
    Avatar de vincent.mbg
    Homme Profil pro
    Développeur Python
    Inscrit en
    Décembre 2007
    Messages
    327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Python

    Informations forums :
    Inscription : Décembre 2007
    Messages : 327
    Points : 618
    Points
    618
    Par défaut
    Il y a une petit différence de performance entre
    a = a + 1
    a += 1
    même si dans le deuxième cas un nouvel objet et quand même crée,
    L'interpréteur python accédé à la valeur de a qu'une seule fois
    Mon guide pour apprendre Tkinter - N'oubliez pas de consulter les FAQ Python ou de visiter mon blog

  11. #11
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    723
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 723
    Points : 923
    Points
    923
    Par défaut
    Je ne vois pas comment ça pourrait différer en performances, à part si += appelle + ou inversement. Et puis un test simple montre que les 2 méthodes sont comparables :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >>> from timeit import Timer
    >>> t1 = Timer("a += 1", "a = 0")
    >>> t2 = Timer("a = a + 1", "a = 0")
    >>> t1.timeit()
    0.10001778602600098
    >>> t2.timeit()
    0.098962068557739258

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 99
    Points : 102
    Points
    102
    Par défaut
    @dapounet: Bien vu, j'étais resté sur ce que j'avais lu et qui disait que c'était complètement équivalent. J'aurais du aller voir la doc précise

Discussions similaires

  1. [IShellLink] Problème de modification de raccourci
    Par Alcatîz dans le forum Windows
    Réponses: 2
    Dernier message: 17/11/2005, 10h39
  2. Réponses: 19
    Dernier message: 28/10/2005, 18h29
  3. Problème de raffraichissement de listes
    Par blondin01 dans le forum Access
    Réponses: 7
    Dernier message: 13/10/2005, 13h31
  4. Problème pour positionner une liste déroulante
    Par ouckileou dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 30/09/2004, 02h05
  5. [débutant] Problème JSplitPane (modif :InternalFrame)
    Par pingoui dans le forum Agents de placement/Fenêtres
    Réponses: 61
    Dernier message: 03/09/2004, 18h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo