Par exemple, j'ai deux dict:
Dict A: {'a': 1, 'b': 2, 'c': 3}
Dict B: {'b': 3, 'c': 4, 'd': 5}
J'ai besoin d'une manière pythonique de «combiner» deux dicts de telle sorte que le résultat soit:
{'a': 1, 'b': 5, 'c': 7, 'd': 5}
C'est-à-dire: si une clé apparaît dans les deux dicts, ajoutez leurs valeurs, si elle apparaît dans un seul dict, conservez sa valeur.
python
dictionary
Derrick Zhang
la source
la source
sum(counters)
ne fonctionne pas, malheureusement.sum()
une valeur de départ, avecsum(counters, Counter())
.+=
à effectuer la sommation sur place.res = counters[0]
, alorsfor c in counters[1:]: res += c
.update()
lieu de+=
:for c in counters[1:]: res.update(c)
.Une solution plus générique, qui fonctionne également pour les valeurs non numériques:
ou encore plus générique:
Par exemple:
la source
for k in b.viewkeys() & a.viewkeys()
, lors de l' utilisation de python 2.7 , et ignorer la création d'ensembles.set(a)
retourne le jeu de clés plutôt que le jeu de tuples? Quelle en est la raison?list({..})
,for k in {...}
etcoperator.mul
de préciser que ce code est générique et ne se limite pas à ajouter des chiffres.{**a, **b, **{k: op(a[k], b[k]) for k in a.keys() & b}}
devrait fonctionner dans Python 3.5+.la source
for x in set(itertools.chain(A, B))
plus logique? L'utilisation de set on dict est un peu absurde, car les clés sont déjà uniques? Je sais que c'est juste une autre façon d'obtenir un jeu de clés, mais je trouve cela plus déroutant que d'utiliseritertools.chain
(ce qui implique que vous savez ce queitertools.chain
ça fait)Intro: Il existe (probablement) les meilleures solutions. Mais vous devez le savoir et vous en souvenir et parfois vous devez espérer que votre version Python n'est pas trop ancienne ou quel que soit le problème.
Ensuite, il y a les solutions les plus «hacky». Ils sont grands et courts mais parfois difficiles à comprendre, à lire et à retenir.
Il existe cependant une alternative qui consiste à essayer de réinventer la roue. - Pourquoi réinventer la roue? - Généralement parce que c'est un très bon moyen d'apprendre (et parfois simplement parce que l'outil déjà existant ne fait pas exactement ce que vous voudriez et / ou comme vous le voudriez) et le plus simple si vous ne savez pas ou ne me souviens pas de l'outil parfait pour votre problème.
Donc , je propose de réinventer la roue de la
Counter
classe à partir ducollections
module (en partie au moins):Il y aurait probablement d'autres façons de l'implémenter et il existe déjà des outils pour le faire, mais il est toujours agréable de visualiser comment les choses fonctionneraient fondamentalement.
la source
la source
Celui sans importations supplémentaires!
Il s'agit d'un standard pythonique appelé EAFP (plus facile à demander pardon que permission). Le code ci-dessous est basé sur cette norme python .
EDIT: merci à jerzyk pour ses suggestions d'amélioration.
la source
Counter()
Résumer définitivement le s est la façon la plus pythonique de procéder dans de tels cas, mais seulement si cela donne une valeur positive . Voici un exemple et comme vous pouvez le voir, il n'y a pasc
de résultat après avoir annulé lac
valeur de 's dans leB
dictionnaire.En effet, les
Counter
s ont été principalement conçus pour fonctionner avec des entiers positifs pour représenter les nombres en cours (le nombre négatif n'a pas de sens). Mais pour aider avec ces cas d'utilisation, python documente la plage minimale et les restrictions de type comme suit:Donc, pour contourner ce problème après avoir additionné votre compteur, vous pouvez l'utiliser
Counter.update
pour obtenir la sortie désirée. Cela fonctionne commedict.update()
mais ajoute des nombres au lieu de les remplacer.la source
OU
Vous pouvez également utiliser Counter comme @Martijn l'a mentionné ci-dessus.
la source
Pour un moyen plus générique et extensible, consultez mergedict . Il utilise
singledispatch
et peut fusionner des valeurs en fonction de ses types.Exemple:
la source
Depuis python 3.5: fusion et sommation
Merci à @tokeinizer_fsj qui m'a dit dans un commentaire que je n'avais pas complètement compris le sens de la question (je pensais que ajouter signifiait simplement ajouter des clés qui finalement étaient différentes dans les deux dictatures et, à la place, je voulais dire que les valeurs de clé communes doit être additionnée). J'ai donc ajouté cette boucle avant la fusion, afin que le deuxième dictionnaire contienne la somme des clés communes. Le dernier dictionnaire sera celui dont les valeurs dureront dans le nouveau dictionnaire qui est le résultat de la fusion des deux, donc je pense que le problème est résolu. La solution est valide à partir de python 3.5 et des versions suivantes.
Code réutilisable
la source
b
est5
(2 + 3), mais votre méthode revient3
.De plus, veuillez noter
a.update( b )
est 2x plus rapide quea + b
la source
Vous pouvez facilement généraliser ceci:
Ensuite, cela peut prendre n'importe quel nombre de dict.
la source
Ceci est une solution simple pour fusionner deux dictionnaires où
+=
peut être appliqué aux valeurs, il ne doit itérer sur un dictionnaire qu'une seule foisla source
Cette solution est facile à utiliser, elle est utilisée comme un dictionnaire normal, mais vous pouvez utiliser la fonction somme.
la source
Qu'en est-il de:
Production:
la source
Les solutions ci-dessus sont parfaites pour le scénario où vous avez un petit nombre de
Counter
s. Si vous en avez une grande liste, quelque chose comme ça est beaucoup plus agréable:La solution ci-dessus résume essentiellement le
Counter
s par:Cela fait la même chose mais je pense que cela aide toujours de voir ce qu'il fait effectivement en dessous.
la source
Fusionner trois dict a, b, c sur une seule ligne sans aucun autre module ou bibliothèque
Si nous avons les trois dict
Fusionner tout avec une seule ligne et renvoyer un objet dict en utilisant
De retour
la source
{'a': 9, 'b': 9, 'd': 90}
. Il vous manque la condition "somme".