web-dev-qa-db-ja.com

Python:値が存在する場合、上書きではなく更新による辞書のマージ

次のように2つの辞書がある場合:

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'):''}

正常に動作します。さらに、2つの辞書の各値を比較し、d1の値が空/なし/ ''の場合にのみd2をd1に更新する場合は、どうすればよいですか?

[EDIT]質問:d2をd1に更新するとき、同じキーが存在する場合、空の値ではなく数値(d1またはd2のいずれか)のみを維持したいと思います。両方の値が空の場合、空の値を維持しても問題ありません。両方に値がある場合、d1-valueはそのままである必要があります。 :)(lotsa 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.

提案するのを手伝ってください。

ありがとう。

41
siva

順番を入れ替えるだけです:

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

ところで、潜在的に高速な update メソッドにも興味があるかもしれません。

Python 3では、最初にビューオブジェクトをリストにキャストする必要があります。

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

空の文字列を特殊なケースにしたい場合は、次のことができます。

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。 d1の値がNoneでない場合にのみ、d1のキー/値のペアでd2を更新します」(偽):

>>> 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

in-placeソリューションです(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

ここに別のin-placeソリューションがあります。これはエレガントではありませんが、潜在的にはより効率的です。また、leaving d2 unmodified

# 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)の代わりにdict(d2.items() + d1.items())

5
warvariuc

d2の既存のキー/値を上書きせずにd1に存在しないd2d2キー/値に追加するには:

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

同じサイズとキーの辞書がある場合、次のコードを使用できます。

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