544 votes

Python "extend" pour un dictionnaire

Quelle est la meilleure façon d'étendre un dictionnaire avec un autre tout en évitant l'utilisation d'un for boucle ? Par exemple :

>>> a = { "a" : 1, "b" : 2 }
>>> b = { "c" : 3, "d" : 4 }
>>> a
{'a': 1, 'b': 2}
>>> b
{'c': 3, 'd': 4}

Résultat :

{ "a" : 1, "b" : 2, "c" : 3, "d" : 4 }

Quelque chose comme :

a.extend(b)  # This does not work

25 votes

Je savais que pour les listes [], alors je suppose que peut être le travail pour d'autres, pas extrange ;-)

0 votes

Cette question n'est pas définie de manière unique, car l'exemple doit couvrir le cas où a et b ont des clés communes.

803voto

Nick Fortescue Points 18829

7 votes

Après avoir lu la documentation, on comprendra pourquoi il existe une "mise à jour" mais pas d'"extension".

83 votes

Gardez à l'esprit que update() modifie directement le dict et retourne None.

7 votes

Mais qu'en est-il si vous voulez seulement étendre le dict avec des valeurs qui sont no déjà définies (c'est-à-dire qu'elles n'écrasent pas les valeurs existantes) ? Par exemple, mettre à jour un dict {"a":2, "b":3} avec dictée {"b":4, "c":5} à la dictée {"a":2, "b":3,"c":5} ? Bien sûr, il est possible d'utiliser update() en déplaçant certains éléments, mais ce serait mieux si cela pouvait se faire en une seule ligne...

210voto

Tom Leys Points 10453

Un beau bijou dans cette question fermée :

La "méthode oneliner", qui ne modifie aucune des dicts d'entrée, est la suivante

basket = dict(basket_one, **basket_two)

Apprendre quoi **basket_two (le ** ) signifie ici .

En cas de conflit, les éléments de basket_two remplaceront celles de basket_one . En matière de one-liners, celui-ci est assez lisible et transparent, et je n'hésite pas à l'utiliser chaque fois qu'un dicton qui est un mélange de deux autres est utile (tout lecteur qui a du mal à le comprendre sera en fait très bien servi par la façon dont celui-ci l'incite à s'informer sur dict y el ** forme;-). Ainsi, par exemple, des utilisations comme :

x = mungesomedict(dict(adict, **anotherdict))

sont des occurrences raisonnablement fréquentes dans mon code.

Soumis à l'origine par Alex Martelli

Nota: En Python 3, cela ne fonctionnera que si chaque clé de basket_two est un fichier de type string .

4 votes

Documentation pour dict est facile à trouver tandis que ** est un peu plus délicat (le mot-clé est kwargs ). Voici une bonne explication : saltycrane.com/blog/2008/01/

4 votes

Cela peut être utilisé pour générer une deuxième variable avec une seule commande, alors que basket_one.update(<dict>) comme son nom l'indique, met à jour un dictionnaire existant (ou un dictionnaire cloné).

2 votes

Notez qu'en Python 3, les noms des arguments, et donc les clés de l'option **anotherdict doivent être des chaînes de caractères.

70voto

Vlad Bezden Points 5024

Avez-vous essayé d'utiliser la compréhension du dictionnaire avec la cartographie du dictionnaire :

a = {'a': 1, 'b': 2}
b = {'c': 3, 'd': 4}

c = {**a, **b}
# c = {"a": 1, "b": 2, "c": 3, "d": 4}

Une autre façon de faire est d'utiliser dict(iterable, **kwarg)

c = dict(a, **b)
# c = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

En Python 3.9, vous pouvez ajouter deux dictées en utilisant l'opérateur union |.

# use the merging operator |
c = a | b
# c = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

24voto

vartec Points 53382
a.update(b)

Ajoutera les clés et les valeurs de b a a en écrasant s'il existe déjà une valeur pour une clé.

18voto

eblume Points 516

Comme d'autres l'ont mentionné, a.update(b) pour certains dicts a y b permettra d'atteindre le résultat que vous avez demandé dans votre question. Toutefois, je tiens à souligner que j'ai souvent vu les extend La méthode de mappage/réglage des objets désire que dans la syntaxe a.extend(b) , a ne doivent PAS être écrasées par les valeurs de l'option b Les valeurs de l'UE. a.update(b) écrase a et n'est donc pas un bon choix pour les valeurs de la extend .

Notez que certaines langues appellent cette méthode defaults o inject car il peut être considéré comme un moyen d'injecter les valeurs de b (qui peuvent être un ensemble de valeurs par défaut) dans un dictionnaire sans écraser les valeurs qui peuvent déjà exister.

Bien sûr, vous pouvez simplement noter que a.extend(b) est presque identique à b.update(a); a=b . Pour supprimer l'affectation, vous pouvez procéder ainsi :

def extend(a,b):
    """Create a new dictionary with a's properties extended by b,
    without overwriting.

    >>> extend({'a':1,'b':2},{'b':3,'c':4})
    {'a': 1, 'c': 4, 'b': 2}
    """
    return dict(b,**a)

Merci à Tom Leys pour cette idée intelligente d'utiliser une méthode sans effet secondaire. dict constructeur pour extend .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X