How to update Python dictionary value without overwriting if value is list?

dictのupdateは一撃でラクチンなんだけれども。

仮に、以下が目的の操作ではないとしたら?

1 >>> d1 = {"a": "b", "dl": {"lst": [1, 2]}}
2 >>> d2 = {"a": "b", "dl": {"lst": [3, 4]}}
3 >>> d1.update(d2)
4 >>> d1
5 {'a': 'b', 'dl': {'lst': [3, 4]}}

つまり、リスト要素は append、が望みのものだとしたら?

これがまぁ、ニーズないのかな、標準にはないようで。

例によって StackOverflow に、「似た」ニーズのトピックがあった。これは、2つの辞書のキーが同じで、値が辞書どうしならばマージする、というもので、今やりたいことに通ずる。ゆえ、ここで挙がっていた解をちょいと改変:

 1 >>> def mergedicts(d1, d2):
 2 ...     for k in set(d1.keys()).union(d2.keys()):
 3 ...         if k in d1 and k in d2:
 4 ...             if isinstance(d1[k], (dict,)) and \
 5 ...                     isinstance(d2[k], (dict,)):
 6 ...                 yield (k, dict(mergedicts(d1[k], d2[k])))
 7 ...             elif isinstance(d1[k], (list, tuple,)) and \
 8 ...                     isinstance(d2[k], (list, tuple,)):
 9 ...                 yield (k, d1[k] + d2[k])
10 ...             else:
11 ...                 yield (k, d2[k])
12 ...         elif k in d1:
13 ...             yield (k, d1[k])
14 ...         else:
15 ...             yield (k, d2[k])
16 ...
17 >>> 
18 >>> d1 = {"a": "b", "dl": {"lst": [1, 2]}}
19 >>> d2 = {"a": "b", "dl": {"lst": [3, 4]}}
20 >>> dict(mergedicts(d1, d2))
21 {'a': 'b', 'dl': {'lst': [1, 2, 3, 4]}}
22 >>> 
23 >>> 
24 >>> d1 = {"a": "b", "dl": {"lst": [1, 2]}}
25 >>> d2 = {"a": "XX", "dl": {"lst": [3, 4]}}
26 >>> dict(mergedicts(d1, d2))
27 {'a': 'XX', 'dl': {'lst': [1, 2, 3, 4]}}
28 >>> 
29 >>> 
30 >>> d1 = {"a": "b", "dl": {"lst": [1, 2], "ind1": 3}}
31 >>> d2 = {"a": "XX", "dl": {"lst": [3, 4], "ind2": 5}}
32 >>> dict(mergedicts(d1, d2))
33 {'a': 'XX', 'dl': {'lst': [1, 2, 3, 4], 'ind1': 3, 'ind2': 5}}
34 >>> 

list, tuple に「対応出来そう」なフリはしてますけど、list + tuple は出来ないんで、どうしてもこれがしたければ措置する必要はあります。