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 :

Copier un dictionnaire par une list comprehension


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut Copier un dictionnaire par une list comprehension
    Bonjour à tous - Je débute dans Python (en fait je commence à grenouiller pas trop mal) mais là, j'aimerais copier un dictionnaire en passant par une list comprehension et je m'en sors mal.

    Exemple: j'ai un dictionnaire de ce type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    source={ "a" : 5, "b" : 12 }
    Que j'aimerais recopier dans un autre. La solution de base serait de taper simplement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    dest={}
    for k, v in source.items(): dest[k]=v
    Mais j'ai commencé à regarder les list comprehension et j'aimerais utiliser cette méthode pour copier mon dico.
    Après plusieurs tests et recherches, je suis arrivé à cette syntaxe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    dest={}
    [dest.setdefault(k, f) for k, v in a.items()]
    Ca marche bien, j'ai bien dest qui est un dictionnaire copie de source mais cette instruction m'affiche en plus les valeurs de source.

    Bon, j'ai un peu de mal à bien piger ce truc. Si quelqu'un avait une idée ce serait sympa...

    Merci
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  2. #2
    Membre émérite
    Avatar de GnuVince
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2004
    Messages
    679
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2004
    Messages : 679
    Par défaut
    Pourquoi une compréhension de liste? Utilise copy.deepcopy()

  3. #3
    Membre émérite

    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
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    dest={}
    [dest.setdefault(k, f) for k, v in a.items()]
    Ca t'affiche le résultat étant donné que tu es en mode interactif.
    Personnellement je ne vois pas trop l'intérêt d'utiliser une list comprehension pour ça, étant donné que tu génères une liste (justement celle qui s'afiche) pour rien. La boucle for est beaucoup plus adaptée, ou, comme l'a dit GnuVince, une copie copy.copy() ou copy.deepcopy()

  4. #4
    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,

    Une solution très simple pour copier un dictionnaire:

    Ce qui fait une copie superficielle (comme copy.copy()).

    Pour vérifier, fais:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dest['toto'] = 'machin'
    Tu pourras ainsi constater que les modifs de dest ne se répercutent pas sur source:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    print source   # affiche: { "a" : 5, "b" : 12 }
    print dest   # affiche: {'a': 5, 'b': 12, 'toto': 'machin'}
    [EDIT]

    Sinon, pour les "list comprehension": elles sont considérées comme des expressions et renvoient des listes. C'est donc un peu artificiel ici de les utiliser puisque l'affectation qui t'interesse, c'est dest.setdefault() et pas du tout la liste retournée. Cependant, ça marche, et dans le mode programme ça n'affiche pas la liste des valeurs.

    Autres manières de copier source dans dest:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    dest.update(source)
    dest = source.copy()
    Tyrtamos

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Merci à tous. Bon, j'ai voulu tenter un truc idiot et c'est bien de le dire (normal quand on débute) donc c'est pas une bonne idée et vous m'avez montré plein de solutions intéressantes en remplacement.
    Mais justement dans ces solutions y a-t-il une différence (ou un avantage quelconque) entre
    ou
    ???
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    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
    A ma connaissance, pour des objets composés (listes, dictionnaires, instances de classe), il faut distinguer 3 cas:

    1- dest=source ne crée pas de copie, mais crée simplement un nouvel accès au même objet "source". Toute modif de dest sera appliquée aussi à source.

    2- dest=copy.copy(source), ainsi que toutes les autres méthodes vues plus haut sauf deepcopy, fait une copie dite "superficielle", c'est à dire que la structure de l'objet est recopiée, mais que cette structure pointe toujours sur les mêmes éléments de base (nombre, chaînes, ...). Cela suffit en général: la modif de dest n'est pas répercutée sur source.

    3- dest=copy.deepcopy(source) fait une copie dite "profonde", c'est à dire que tout est copié, y compris les éléments de base pointés par la structure de l'objet. C'est rarement nécessaire, et cela peut avoir des inconvénients en cas d'objets complexes avec boucles.

    cf une info sur le web: http://quentel.pierre.free.fr/python...dule-copy.html

    Tyrtamos

    [EDIT] je viens cependant de lire dans un de mes livres Python que, pour les dictionnaires, la fonction dico.items() fournit une copie profonde des éléments renvoyés.

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    A ma connaissance, pour des objets composés (listes, dictionnaires, instances de classe), il faut distinguer 3 cas:

    1- dest=source ne crée pas de copie, mais crée simplement un nouvel accès au même objet "source". Toute modif de dest sera appliquée aussi à source.

    2- dest=copy.copy(source), ainsi que toutes les autres méthodes vues plus haut sauf deepcopy, fait une copie dite "superficielle", c'est à dire que la structure de l'objet est recopiée, mais que cette structure pointe toujours sur les mêmes éléments de base (nombre, chaînes, ...). Cela suffit en général: la modif de dest n'est pas répercutée sur source.

    3- dest=copy.deepcopy(source) fait une copie dite "profonde", c'est à dire que tout est copié, y compris les éléments de base pointés par la structure de l'objet. C'est rarement nécessaire, et cela peut avoir des inconvénients en cas d'objets complexes avec boucles.

    cf une info sur le web: http://quentel.pierre.free.fr/python...dule-copy.html

    Tyrtamos

    [EDIT] je viens cependant de lire dans un de mes livres Python que, pour les dictionnaires, la fonction dico.items() fournit une copie profonde des éléments renvoyés.
    Merci J'aime beaucoup Python mais ça m'énerve de me sentir aussi "ignorant" de toutes ses subtilités...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 25/01/2007, 08h54
  2. [VBA-E]Mise à jour de cellule alimentée par une liste
    Par moritan dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 19/01/2007, 06h11
  3. Apparition de texte par une liste de sélection
    Par Coach_nono dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 11/01/2007, 21h54
  4. Réponses: 1
    Dernier message: 04/04/2006, 16h09
  5. [Debutant]Remplacer une liste de valeur par une liste de val
    Par Sebbo dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 31/03/2006, 12h15

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