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 :

[Python 3.5.1] Bug ou incompréhension avec append()


Sujet :

Python

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2016
    Messages : 6
    Par défaut [Python 3.5.1] Bug ou incompréhension avec append()
    Bonjour les amis,

    Voilà mon problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> ruru = [1,2]
    >>> tutu = ruru
    >>> tutu.append(3)
    >>> print(ruru,tutu)
    [1, 2, 3] [1, 2, 3]
    Pourquoi ruru a été affecté par le append ???
    Pour moi tutu devrait être [1,2,3] et ruru devrait rester inchangé [1,2]

    Savez-vous pourquoi ? et comment éviter ce problème ?

    Merci de votre aide.

  2. #2
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    L'affectation tutu = ruru ne fait que copier l'adresse de ruru pour l'affecter à tutu.

    D'ailleurs, on doit avoir id(tutu)==id(ruru), ce qui montre bien que les 2 variables pointent sur les mêmes données.

    Si tutu doit être une liste nouvelle avec les mêmes valeurs que ruru, il faut faire une copie de ruru:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tutu = ruru[:] # ou tutu = ruru.copy()

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2016
    Messages : 6
    Par défaut
    Merci beaucoup.

    Mon problème c'est que j'ai utilisé beaucoup de variable1 = variable2 dans mon programme donc je dois m'attendre à d'autres problèmes de ce type, mais grâce à toi je saurais pourquoi !!!

    Merci encore

  4. #4
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    Bonjour

    pourrais-tu nous citer un langage où, dans le même esprit, une affectation se transformerait (par miracle ?) en une copie distincte ?

    Python est souvent stigmatisé sur ce genre de choses mais (je ne connais pas tous les langages !) dans ceux que je connais, une affectation reste une affectation (de valeur ou d'adresse)

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2016
    Messages : 6
    Par défaut
    Je fais que du python depuis plusieurs années maintenant donc je ne me souviens plus du fonctionnement des autres langages.

    En tous cas, j'ai toujours fonctionné avec cette logique et ça me paraissait normal que ça soit juste la valeur qui soit copié.

    Après c'est ce que j'avais en tête et forte heureusement tout ce que j'ai dans la tête n'est pas une vérité absolue.

  6. #6
    Membre chevronné
    Homme Profil pro
    .
    Inscrit en
    Juin 2002
    Messages
    239
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : .
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2002
    Messages : 239
    Par défaut
    Bonjour.

    Cela fait plus de 40 ans que je programme ( j'ai commencé en Fortran en Octobre 1971 ) et je partage l'étonnement de funestra :
    je trouve totalement anormal qu'une affectation du type tutu = ruru ne fasse que copier l'adresse de ruru pour l'affecter à tutu.

    Ce comportement de Python est susceptible de tromper les programmeurs qui sont habitués à d'autres langages.

    En fait, ce comportement déplorable ne s'applique qu'aux types composés.
    L'affectation y = x lorsque x est un entier crée bien une nouvelle variable y distincte de x ; je viens de le vérifier avec Python 3.5.1.

    Dans la plupart des langages, les variables de type composé sont passées aux fonctions par adresse et non par valeur.
    Cela se comprend puisqu'il faut placer la variable sur la pile et qu'une variable de type composé peut contenir un nombre arbitraire d'éléments.
    Passer l'adresse plutôt que la valeur est donc parfaitement légitime et est bien connu des programmeurs.

    Mais faire la même chose dans une affectation au niveau des variables globales me semble abusif ...

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 718
    Par défaut
    Salut,

    Citation Envoyé par Prof Voir le message
    Ce comportement de Python est susceptible de tromper les programmeurs qui sont habitués à d'autres langages.

    En fait, ce comportement déplorable ne s'applique qu'aux types composés.
    L'affectation y = x lorsque x est un entier crée bien une nouvelle variable y distincte de x ; je viens de le vérifier avec Python 3.5.1.
    En Python, une variable est une association dans une tableau associatif ou "dict" entre une clef et un objet.
    Si on écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> d = dict()
    >>> d['x'] = 1
    >>> d['y'] = d['x']
    on voit peut être mieux l'association entre 'x' et 'y' avec l'objet int('1') qu'en écrivant:
    qui est une forme condensée de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    >>> globals()['x'] = 1
    >>> globals()['y'] = globals()['y']
    Mais comme le note plxpy, une assignation reste une assignation alors qu'appliquer une méthode à un objet aura un comportement différent suivant que l'objet est mutable ou pas.
    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> s = 'abcd'
    >>> t = s
    >>> t = t.upper()
    >>> s, t
    ('abcd', 'ABCD')
    >>>
    Une chaine de caractère (str) n'est pas mutable: si on applique une méthode qui mets tous les caractères en majuscule, çà retournera une autre chaine de caractères sans modifier l'objet d'origine.
    Par contre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> L = T = [1, 2, 3]
    >>> T[0] = 'xx'
    >>> L, T
    (['xx', 2, 3], ['xx', 2, 3])
    Parce qu'une liste est "mutable"...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Membre chevronné
    Homme Profil pro
    .
    Inscrit en
    Juin 2002
    Messages
    239
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : .
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2002
    Messages : 239
    Par défaut
    Bonsoir

    Merci pour ces explications.

    J'ai effectivement trouvé dans la documentation de Python ( chapitre 3. Data Model ) des détails sur l'implémentation des données.
    La notion d'objet mutable y est longuement expliquée.
    Comme quoi il faut toujours lire la doc ...

    Au passage j'ai découvert que mon affirmation précédente
    L'affectation y = x lorsque x est un entier crée bien une nouvelle variable y distincte de x ; je viens de le vérifier avec Python 3.5.1.
    était fausse : j'avais mal vérifié.

Discussions similaires

  1. Réponses: 4
    Dernier message: 25/09/2006, 14h57
  2. Bug internet explorer avec hotmail.com
    Par rub091 dans le forum IE
    Réponses: 8
    Dernier message: 31/05/2006, 09h21
  3. Gros bug SQL Server avec caractère "²"
    Par Oluha dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 26/05/2005, 14h31
  4. incompréhension avec ado
    Par Orgied dans le forum Bases de données
    Réponses: 3
    Dernier message: 19/05/2004, 18h24

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