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 :

Dictionnaire : copie "simple" (duplication sans référence au dictionnaire d'origine !)


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de Nothus
    Homme Profil pro
    aucun
    Inscrit en
    Juillet 2009
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : aucun
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2009
    Messages : 200
    Billets dans le blog
    27
    Par défaut Dictionnaire : copie "simple" (duplication sans référence au dictionnaire d'origine !)
    Bonjour à tous,

    Tout est un peu dans le titre : codant une bête fonction de gestion de matrice (à dimensions multiples), et lançant le programme, j'ai fini par perdre patience à ne pas comprendre une erreur simple. Lorsque je décalais dans une matrice une colonne ou une ligne (ou d'une dimension à l'autre), je modifiais l'objet voulu mais aussi l'objet d'origine (qui devait lui, demeurer intact).

    Non sans difficulté (sic !), j'ai fini par remettre la main sur l'erreur, un dictionnaire semblant ne pouvoir ""simplement"" se copier par affectation. En somme Dict2 = Dict1, Dict2 reste une référence de Dict1.
    > Question 1: je suis dans le vrai ? Je n'ai pas trouvé spécialement clair la documentation à ce sujet (à ce propos si vous connaissez une bonne traduction...).

    Python n'est pas mon langage de programmation "natif" (PHP), et j'avoue que je suis face à un abyme de perplexité face à ce comportement.
    > Question 2: Comment dupliquer un dictionnaire (avec tout ce qu'il contient, ordre et affectation interne), sans créer juste une référence supplémentaire à son original? Pour la liste j'ai trouvé [:], mais qui ne fonctionne pas avec les dictionnaires. J'ai essayé Dict2 = dict(Dict1), mais sans résultat probant (création d'une référence). J'ai finalement essayé Dict2 = dict() puis boucler ligne à ligne les affectations de Dict1 dans Dict2 (et devinez quoi? Ben ça crée une référence).

    J'ai même essayé Dict2 = dict((list(Dict1)[:])) - sait-on jamais...

    Accessoirement, c'est ce genre de petit détail rageant qui vous dit que tous les langages ne sont pas tous aussi «accessibles» qu'on peut bien le lire parfois et, pour être honnête, ça donne l'impression d'un langage pas très abouti, même si je l'aime bien pour des petites routines... :/
    > Question 3: Python, bon pour apprendre mais pas pour travailler? (ne me tapez pas)

    Citation Envoyé par mont29 Voir le message
    Autrement dit, la copie d’une string (ou int, float, etc.) donne toujours un nouvel objet, alors que la copie d’une liste (ou d’un dict, ou n’importe quel objet évolué) est “shallow”, c’est le même objet qui est assigné à la copie…

    D’où la vicieuse subtilité qui t’a posé problème : l’expression d’initialisation par défaut des variables d’une fonction est évaluée une seule fois, lors de la construction de cette fonction par le parseur, et les valeurs ainsi obtenues sont copiées à chaque appel de cette fonction, si nécessaire – donc, tu te retrouve toujours avec la même liste ! Oui, c’est vraiment vicieux, et bravo pour avoir trouvé une solution tout seul
    Bonne fin d'après-midi!

  2. #2
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour,

    En effet vous ne faite qu'ajouter une référence.
    Vous pouvez faire dico2 = dict(dico1).

    @+

  3. #3
    Membre Expert
    Avatar de Nothus
    Homme Profil pro
    aucun
    Inscrit en
    Juillet 2009
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : aucun
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2009
    Messages : 200
    Billets dans le blog
    27
    Par défaut
    Déjà fait, même résultat. Cela fait une référence supplémentaire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Matrice2 = dict(Matrice)
        for item in Matrice:
        if (item+pas)<=NbreLignes:
            Matrice2[item+pas][numero_colonne] = Matrice[item][numero_colonne]
        else:
            Matrice2[((item+pas)-NbreLignes)][numero_colonne] = Matrice[item][numero_colonne]
    NB: je travaille dans une fonction. Mais je doute que ça change quelque chose ?

  4. #4
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Citation Envoyé par Nothus Voir le message
    Déjà fait, même résultat. Cela fait une référence supplémentaire.
    Ne confondez vous pas ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> dico2 = dict(dico1)
    >>> id(dico1)
    23011296
    >>> id(dico2)
    23722784

  5. #5
    Membre Expert
    Avatar de Nothus
    Homme Profil pro
    aucun
    Inscrit en
    Juillet 2009
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : aucun
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2009
    Messages : 200
    Billets dans le blog
    27
    Par défaut
    Effectivement, autant pour moi, ça fait un objet différent.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    {1: '0', 2: '1', 3: '2', 4: '3', 5: '4', 6: '5', 7: '6'}
    {1: '7', 2: '8', 3: '9', 4: '0', 5: '1', 6: '2', 7: '3'}
    {1: '4', 2: '5', 3: '6', 4: '7', 5: '8', 6: '9', 7: '0'}
    {1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7'}
    {1: '8', 2: '9', 3: '0', 4: '1', 5: '2', 6: '3', 7: '4'}
    {1: '5', 2: '6', 3: '7', 4: '8', 5: '9'}
    37484992
    ---Fct---
    ---37499360
    ---37484992
    ---Fin Fct---
    ---37499360
    ---37484992
    ---------------
    {1: '0', 2: '1', 3: '2', 4: '3', 5: '4', 6: '5', 7: '6'}
    {1: '7', 2: '1', 3: '9', 4: '0', 5: '1', 6: '2', 7: '3'}
    {1: '4', 2: '1', 3: '6', 4: '7', 5: '8', 6: '9', 7: '0'}
    {1: '1', 2: '1', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7'}
    {1: '8', 2: '1', 3: '0', 4: '1', 5: '2', 6: '3', 7: '4'}
    {1: '5', 2: '1', 3: '7', 4: '8', 5: '9'}
    37499360
    Mais le résultat reste désespérément le même. Bon donc c'est juste que je me plante plus largement dans ma fonction !

    Mais c'est un autre problème maintenant ! Merci beaucoup !

  6. #6
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Citation Envoyé par Nothus Voir le message
    > Question 1: je suis dans le vrai ? Je n'ai pas trouvé spécialement clair la documentation à ce sujet (à ce propos si vous connaissez une bonne traduction...).
    C'est ce qui se passe pour tout bon langage classique avec gestion de mémoire automatique, même PHP, l me semble. Tu travailles non pas avec les objets, mais avec des références sur ces objets. = ne fait qu'affecter, ça ne crée rien de nouveau

  7. #7
    Membre Expert
    Avatar de Nothus
    Homme Profil pro
    aucun
    Inscrit en
    Juillet 2009
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : aucun
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2009
    Messages : 200
    Billets dans le blog
    27
    Par défaut
    Oui pour les objets (sous PHP5 tout au moins). Mais pour les tableaux non, c'est une assignation de valeur.

    http://php.net/manual/fr/language.oop5.cloning.php

  8. #8
    Membre Expert
    Avatar de Nothus
    Homme Profil pro
    aucun
    Inscrit en
    Juillet 2009
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : aucun
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2009
    Messages : 200
    Billets dans le blog
    27
    Par défaut
    Je vais paraître bête mais tant pis : un dictionnaire sous Python (3), c'est un type comme un autre (à savoir comme se comporte un tableau sous PHP) ou non ?

    J'imagine, vu que l'on parle de référence, que Python le gère comme un objet, c-à-d une sorte de classe déguisée ?

  9. #9
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Ce n’est même pas une “classe déguisée”, c’est une classe, d’où l’on peut dériver d’autres classes, et qui dérive elle-même de la classe de base 'object'… tout comme int, str, etc.

    La seule “exception” à ce principe de référence, ce sont les types (ou classes) immutable (int, float, str, bytes, tuple), qui sont toujours passés par valeur (pour simplifier).

  10. #10
    Membre Expert
    Avatar de Nothus
    Homme Profil pro
    aucun
    Inscrit en
    Juillet 2009
    Messages
    200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : aucun
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2009
    Messages : 200
    Billets dans le blog
    27
    Par défaut
    Merci beaucoup de vos réponses. Il faut que je repasse par les bancs de la fac, encore quelques (grosses) lacunes dans les bases !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Difference entre [Simple quote] & [Double quote]
    Par Invité dans le forum SQL
    Réponses: 3
    Dernier message: 24/07/2013, 12h24

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