web-dev-qa-db-fra.com

Python: fusion du dictionnaire en mettant à jour mais sans écraser si la valeur existe

Si j'ai 2 dicts comme suit:

d1 = {('unit1','test1'):2,('unit1','test2'):4}
d2 = {('unit1','test1'):2,('unit1','test2'):''}

Afin de les "fusionner":

z = dict(d1.items() + d2.items())
z = {('unit1','test1'):2,('unit1','test2'):''}

Fonctionne bien. De plus que faire, si je souhaite comparer chaque valeur de deux dictionnaires et ne mettre à jour d2 en d1 que si les valeurs en d1 sont vides/Aucune/''?

[EDIT] Question: Lors de la mise à jour de d2 en d1, lorsque la même clé existe, je voudrais conserver uniquement la valeur numérique (soit de d1 ou d2) au lieu de la valeur vide. Si les deux valeurs sont vides, aucun problème de maintien de la valeur vide. Si les deux ont des valeurs, la valeur d1 doit rester. :) (lotsa if-else .. je m'essayerais en attendant)

c'est à dire.

d1 = {('unit1','test1'):2,('unit1','test2'):8,('unit1','test3'):''}
d2 = {('unit1','test1'):2,('unit1','test2'):'',('unit1','test3'):''}

#compare & update codes

z = {('unit1','test1'):2,('unit1','test2'):8, ('unit1','test2'):''} # 8 not overwritten by empty.

veuillez aider à suggérer.

Merci.

41
siva

Changez simplement la commande:

z = dict(d2.items() + d1.items())

Soit dit en passant, vous pourriez également être intéressé par la méthode potentiellement plus rapide update .

Dans Python 3, vous devez d'abord convertir les objets de vue en listes:

z = dict(list(d2.items()) + list(d1.items())) 

Si vous souhaitez mettre des chaînes vides dans un cas spécial, vous pouvez effectuer les opérations suivantes:

def mergeDictsOverwriteEmpty(d1, d2):
    res = d2.copy()
    for k,v in d2.items():
        if k not in d1 or d1[k] == '':
            res[k] = v
    return res
37
phihag

Python 2.7. Met à jour d2 avec les paires clé/valeur d1, mais uniquement si la valeur d1 n'est pas Aucune '' (Faux):

>>> d1 = dict(a=1,b=None,c=2)
>>> d2 = dict(a=None,b=2,c=1)
>>> d2.update({k:v for k,v in d1.iteritems() if v})
>>> d2
{'a': 1, 'c': 2, 'b': 2}
27
Mark Tolonen

Voici une solution en place (elle modifie d2):

# assumptions: d2 is a temporary dict that can be discarded
# d1 is a dict that must be modified in place
# the modification is adding keys from d2 into d1 that do not exist in d1.

def update_non_existing_inplace(original_dict, to_add):
    to_add.update(original_dict) # to_add now holds the "final result" (O(n))
    original_dict.clear() # erase original_dict in-place (O(1))
    original_dict.update(to_add) # original_dict now holds the "final result" (O(n))
    return

Voici une autre solution en place, qui est moins élégante mais potentiellement plus efficace, ainsi que laissant d2 non modifié:

# assumptions: d2 is can not be modified
# d1 is a dict that must be modified in place
# the modification is adding keys from d2 into d1 that do not exist in d1.

def update_non_existing_inplace(original_dict, to_add):
    for key in to_add.iterkeys():
        if key not in original_dict:
            original_dict[key] = to_add[key]
5
aong152

d2.update(d1) au lieu de dict(d2.items() + d1.items())

5
warvariuc

Ajouter à d2 clés/valeurs de d1 qui n'existent pas dans d2 sans remplacer les clés/valeurs existantes dans d2:

temp = d2.copy()
d2.update(d1)
d2.update(temp)
4
Ron Kalian

Dans le cas où vous avez des dictionnaires avec la même taille et les mêmes clés, vous pouvez utiliser le code suivant:

dict((k,v if k in d2 and d2[k] in [None, ''] else d2[k]) for k,v in d1.iteritems())
3
Artsiom Rudzenka