d3 = dict(d1, **d2)
Je comprends que cela fusionne le dictionnaire. Mais est-ce unique? Et si d1 a la même clé que d2 mais une valeur différente? Je voudrais que d1 et d2 soient fusionnés, mais d1 est prioritaire s’il existe une clé en double.
Vous pouvez utiliser la méthode .update()
si vous n'avez plus besoin du d2
original:
Mettez à jour le dictionnaire avec les paires clé/valeur des autres clés écrasant les clés existantes. Retourne
None
.
Par exemple.:
>>> d1 = {'a': 1, 'b': 2}
>>> d2 = {'b': 1, 'c': 3}
>>> d2.update(d1)
>>> d2
{'a': 1, 'c': 3, 'b': 2}
Mettre à jour:
Bien sûr, vous pouvez commencer par copier le dictionnaire afin de créer un nouveau dictionnaire fusionné. Cela peut ou peut ne pas être nécessaire. Si votre dictionnaire contient des objets composés (objets contenant d'autres objets, tels que des listes ou des instances de classe), copy.deepcopy
doit également être pris en compte.
En Python2,
d1={'a':1,'b':2}
d2={'a':10,'c':3}
d1 remplace d2:
dict(d2,**d1)
# {'a': 1, 'c': 3, 'b': 2}
d2 annule d1:
dict(d1,**d2)
# {'a': 10, 'c': 3, 'b': 2}
Ce comportement n’est pas simplement un coup de chance de la mise en œuvre; il est garanti dans la documentation :
Si une clé est spécifiée à la fois dans le fichier argument positionnel et en tant que mot clé argument, la valeur associée à le mot clé est conservé dans le dictionnaire.
Si vous souhaitez que d1
soit prioritaire dans les conflits, procédez comme suit:
d3 = d2.copy()
d3.update(d1)
Sinon, inversez d2
et d1
.
Trey Hunner a publié un article dans le blog de Nice décrivant plusieurs options pour la fusion de plusieurs dictionnaires, notamment (pour python3.3 +) ChainMap et dictionary unpacking .
Ma solution est de définir une fonction merge . Ce n'est pas sophistiqué et ne coûte qu'une ligne. Voici le code dans Python 3.
from functools import reduce
from operator import or_
def merge(*dicts):
return { k: reduce(lambda d, x: x.get(k, d), dicts, None) for k in reduce(or_, map(lambda x: x.keys(), dicts), set()) }
Des tests
>>> d = {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
>>> d_letters = {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j', 10: 'k', 11: 'l', 12: 'm', 13: 'n', 14: 'o', 15: 'p', 16: 'q', 17: 'r', 18: 's', 19: 't', 20: 'u', 21: 'v', 22: 'w', 23: 'x', 24: 'y', 25: 'z', 26: 'A', 27: 'B', 28: 'C', 29: 'D', 30: 'E', 31: 'F', 32: 'G', 33: 'H', 34: 'I', 35: 'J', 36: 'K', 37: 'L', 38: 'M', 39: 'N', 40: 'O', 41: 'P', 42: 'Q', 43: 'R', 44: 'S', 45: 'T', 46: 'U', 47: 'V', 48: 'W', 49: 'X', 50: 'Y', 51: 'Z'}
>>> merge(d, d_letters)
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j', 10: 'k', 11: 'l', 12: 'm', 13: 'n', 14: 'o', 15: 'p', 16: 'q', 17: 'r', 18: 's', 19: 't', 20: 'u', 21: 'v', 22: 'w', 23: 'x', 24: 'y', 25: 'z', 26: 'A', 27: 'B', 28: 'C', 29: 'D', 30: 'E', 31: 'F', 32: 'G', 33: 'H', 34: 'I', 35: 'J', 36: 'K', 37: 'L', 38: 'M', 39: 'N', 40: 'O', 41: 'P', 42: 'Q', 43: 'R', 44: 'S', 45: 'T', 46: 'U', 47: 'V', 48: 'W', 49: 'X', 50: 'Y', 51: 'Z'}
>>> merge(d_letters, d)
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j', 10: 'k', 11: 'l', 12: 'm', 13: 'n', 14: 'o', 15: 'p', 16: 'q', 17: 'r', 18: 's', 19: 't', 20: 'u', 21: 'v', 22: 'w', 23: 'x', 24: 'y', 25: 'z', 26: 'A', 27: 'B', 28: 'C', 29: 'D', 30: 'E', 31: 'F', 32: 'G', 33: 'H', 34: 'I', 35: 'J', 36: 'K', 37: 'L', 38: 'M', 39: 'N', 40: 'O', 41: 'P', 42: 'Q', 43: 'R', 44: 'S', 45: 'T', 46: 'U', 47: 'V', 48: 'W', 49: 'X', 50: 'Y', 51: 'Z'}
>>> merge(d)
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
>>> merge(d_letters)
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j', 10: 'k', 11: 'l', 12: 'm', 13: 'n', 14: 'o', 15: 'p', 16: 'q', 17: 'r', 18: 's', 19: 't', 20: 'u', 21: 'v', 22: 'w', 23: 'x', 24: 'y', 25: 'z', 26: 'A', 27: 'B', 28: 'C', 29: 'D', 30: 'E', 31: 'F', 32: 'G', 33: 'H', 34: 'I', 35: 'J', 36: 'K', 37: 'L', 38: 'M', 39: 'N', 40: 'O', 41: 'P', 42: 'Q', 43: 'R', 44: 'S', 45: 'T', 46: 'U', 47: 'V', 48: 'W', 49: 'X', 50: 'Y', 51: 'Z'}
>>> merge()
{}
Cela fonctionne pour un nombre arbitraire d'arguments de dictionnaire. S'il y avait des clés en double dans ces dictionnaires, la clé du dictionnaire le plus à droite dans la liste des arguments l'emporte.
Comme indiqué ci-dessus, je crois que l’utilisation de d2.update(d1)
est la meilleure approche et que vous pouvez également copier d2
d’abord si vous en avez encore besoin.
Bien que, je tiens à souligner que dict(d1, **d2)
est en fait un mauvais moyen de fusionner des dictionnaires en général puisque les arguments de mots clés doivent être des chaînes, donc cela échouera si vous avez une dict
comme
{
1: 'foo',
2: 'bar'
}