Python: слияние словаря путем обновления, но не перезаписи, если существует значение
Если у меня есть 2 dicts следующим образом:
d1 = {('unit1','test1'):2,('unit1','test2'):4}
d2 = {('unit1','test1'):2,('unit1','test2'):''}
Чтобы "объединить" их:
z = dict(d1.items() + d2.items())
z = {('unit1','test1'):2,('unit1','test2'):''}
Прекрасно работает.
Кроме того, что делать, если я хотел бы сравнить каждое значение двух словарей и обновлять d2 до d1, если значения в d1 пусты /None/ ''?
[EDIT]
Вопрос: При обновлении d2 в d1, когда один и тот же ключ существует, я хотел бы сохранить только числовое значение (либо из d1, либо d2), а не пустое значение. Если оба значения пустые, тогда никаких проблем с сохранением пустого значения. Если оба имеют значения, то значение d1 должно оставаться.:) (lota if-else.. я бы попробовал себя тем временем)
то есть.
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.
пожалуйста, помогите предложить.
Спасибо.
Ответы
Ответ 1
Просто измените порядок:
z = dict(d2.items() + d1.items())
Кстати, вас также может заинтересовать потенциально более быстрый update
метод.
[В ответ на редактирование] Если вы хотите создавать пустые строки в специальном случае, вы можете сделать следующее:
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
Ответ 2
Python 2.7. Обновления d2 с парами ключ/значение d1, но только если значение d1 не равно None, '' (False):
>>> 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}
Ответ 3
d2.update(d1)
вместо dict(d2.items() + d1.items())
Ответ 4
Если у вас есть словари с одинаковыми размерами и ключами, вы можете использовать следующий код:
dict((k,v if k in d2 and d2[k] in [None, ''] else d2[k]) for k,v in d1.iteritems())
Ответ 5
Здесь на месте решение (оно изменяет 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
Здесь другое решение на месте, которое является менее элегантным, но потенциально более эффективным, а также оставляя d2 немодифицированным:
# 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]