wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
一般論としての辞書のマージじゃなくて、具体的な特定のデータ構造についての処理のようなので、そのデータ構造に沿った処理を書く必要があります。
投稿2020/05/16 15:10
総合スコア85901
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2020/05/16 15:17
2020/05/16 15:23
退会済みユーザー
2020/05/16 16:03
2020/05/17 00:21
0
まず、辞書のupdateはその辞書のキー(例では'a','b')で置換(上書き)されるので、値が辞書だったら~のような処理は行いません。
また、'd'が持つリストの連結は辞書のupdateとは異なるロジックなので、これも個別に判断が必要になります。
構造を一般化してそれに応じたロジックを組むべきだと思います。
投稿2020/05/16 15:23
総合スコア1096
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2020/05/16 16:22
2020/05/16 16:29
退会済みユーザー
2020/05/16 16:39
2020/05/16 17:05
退会済みユーザー
2020/05/17 09:40 編集
0
ベストアンサー
dictknife/deepmergeのコードを参考に、リストのマージ部分を修正します。下記importはpython3の標準ライブラリです。(pip install不要)
python
1# Below code referred from https://github.com/podhmo/dictknife 2import copy 3import warnings 4import itertools 5from functools import partial 6 7import sys 8 9if sys.version_info[:2] >= (3, 6): 10 make_dict = dict 11else: 12 from collections import OrderedDict as make_dict 13 14def _deepmerge_extend(left, right, *, dedup=False): 15 if isinstance(left, (list, tuple)): 16 r = left[:] 17 if isinstance(right, (list, tuple)): 18 for e in right: 19 r.append(e) 20 else: 21 r.append(right) 22 return r 23 elif hasattr(left, "get"): 24 if hasattr(right, "get"): 25 r = left.copy() 26 for k in right.keys(): 27 if k in left: 28 r[k] = _deepmerge_extend(r[k], right[k], dedup=dedup) 29 else: 30 r[k] = right[k] 31 return r 32 elif right is None: 33 return left 34 else: 35 raise ValueError 36 else: 37 return right 38 39 40def _deepmerge_replace(left, right): 41 if hasattr(right, "keys"): 42 for k, v in right.items(): 43 if k in left: 44 left[k] = _deepmerge_replace(left[k], v) 45 else: 46 left[k] = copy.deepcopy(v) 47 return left 48 elif isinstance(right, (list, tuple)): 49 return right[:] 50 else: 51 return right 52 53 54def _deepmerge_merge(left, right): 55 if isinstance(left, (list, tuple)): 56 if not isinstance(right, (list, tuple)): 57 right = [right] 58 r = [] 59 for x, y in itertools.zip_longest(left, right): 60 if x is None: 61 r.append(y) 62 elif y is None: 63 r.append(x) 64 else: 65 r.append(_deepmerge_merge(x, y)) 66 return r 67 elif hasattr(left, "get"): 68 if hasattr(right, "get"): 69 r = left.copy() 70 for k in right.keys(): 71 if k in left: 72 r[k] = _deepmerge_extend(r[k], right[k]) 73 else: 74 r[k] = right[k] 75 return r 76 elif right is None: 77 return left 78 else: 79 raise ValueError 80 else: 81 return right 82 83 84METHODS = ["merge", "append", "addtoset", "replace"] 85 86 87def deepmerge(*ds, override=False, method="addtoset"): 88 """deepmerge: methods in {METHODS!r}""".format(METHODS=METHODS) 89 if len(ds) == 0: 90 return make_dict() 91 92 if override: 93 warnings.warn( 94 "override option is deprecated, will be removed, near future", 95 category=DeprecationWarning, 96 ) 97 merge = _deepmerge_replace 98 elif method == "addtoset": 99 merge = partial(_deepmerge_extend, dedup=True) 100 elif method == "append": 101 merge = partial(_deepmerge_extend, dedup=False) 102 elif method == "merge": 103 merge = _deepmerge_merge 104 elif method == "replace": 105 merge = _deepmerge_replace 106 else: 107 raise ValueError( 108 "unavailable method not in {METHODS!r}".format(METHODS=METHODS) 109 ) 110 111 left = ds[0].__class__() 112 113 for right in ds: 114 if not right: 115 continue 116 left = merge(left, right) 117 return left 118 119# --------------------- 120# main 121 122d1 = { 123 "a": 1, 124 "b": { 125 "c": 2, 126 "d": [ 2, 0 ], 127 "e": 4 128 } 129} 130d2 = { 131 "a": 2, 132 "b": { 133 "c": 1, 134 "d": [ 1, 2, 3 ], 135 "f": 5, 136 } 137} 138d3 = { 139 "b": { 140 "d": [ 4 ], 141 } 142} 143 144print(deepmerge(d1,d2,d3))
投稿2020/05/16 15:11
編集2020/05/16 15:18総合スコア820
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2020/05/16 15:25
退会済みユーザー
2020/05/16 15:25
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。