質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
マージ

複数のデータベースやファイル、プログラムなどを決まった手順や規則に従って一つに結合すること。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

2329閲覧

pythonの辞書のmerge(ライブラリなし)

退会済みユーザー

退会済みユーザー

総合スコア0

マージ

複数のデータベースやファイル、プログラムなどを決まった手順や規則に従って一つに結合すること。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/05/16 14:46

編集2020/05/17 11:39

wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

quickquip

2020/05/17 00:59 編集

解決済みでいいのでしょうか? https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12225077652 "質問内容にマルチポストをする理由を書き、他のサイトの投稿へのリンクを貼ってください。また、解決した際には必ずteratail及びすべての投稿に解決した旨と、どのように解決したかを記載してください。"
guest

回答3

0

一般論としての辞書のマージじゃなくて、具体的な特定のデータ構造についての処理のようなので、そのデータ構造に沿った処理を書く必要があります。

投稿2020/05/16 15:10

otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/05/16 15:17

愚直にforループか再帰で辞書の中身見てっていうふうにソートするやりかたでできそうですか?
otn

2020/05/16 15:23

はい。愚直に書くのが分かりやすいと思います。
退会済みユーザー

退会済みユーザー

2020/05/16 16:03

どのようにプログラムになるか教えてくれませんか?bの中を見る方法がわかりません
otn

2020/05/17 00:21

実際のプログラムはかなり面倒くさそうです。 あと、仕様が文章からは不明瞭で、同一キーがあった場合に、あり得る組み合わせすべてに対して対処を決めないといけません。 例から察すると、 ・数値同士⇒あとの方のみ採用? ・リスト同士⇒単純マージ? ・辞書同士⇒再帰処理? ・数値とリストなど異なる型⇒あり得ないので考慮しない?orエラー検出?
guest

0

まず、辞書のupdateはその辞書のキー(例では'a','b')で置換(上書き)されるので、値が辞書だったら~のような処理は行いません。
また、'd'が持つリストの連結は辞書のupdateとは異なるロジックなので、これも個別に判断が必要になります。
構造を一般化してそれに応じたロジックを組むべきだと思います。

投稿2020/05/16 15:23

x98000

総合スコア1096

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/05/16 16:22

bの中のデータにはどのようにアクセスすれはよいのでしょうか
x98000

2020/05/16 16:29

d1のbは d1["b"] 、d1のdは d1["b"]["d"] で取得できます。そういうことではないですか?
退会済みユーザー

退会済みユーザー

2020/05/16 16:39

ごめんなさいそれはわかったのですがうまくならべかえたり上書きする方法や関数のつくりかたがわかりません
x98000

2020/05/16 17:05

基本的なコーディング方法はQAで答えられるものではありません。「関数の作り方」が分からないのであれば、まず参考書やラーニングサイトで基礎知識を増やすべきです。
退会済みユーザー

退会済みユーザー

2020/05/17 09:40 編集

わかりました
guest

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
patapi

総合スコア820

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/05/16 15:25

ありがとうございます。 しかし、これだとd: [2, 1, 4, 0, 2, 3]になりませんでした。
退会済みユーザー

退会済みユーザー

2020/05/16 15:25

'd': [2, 0, 1, 2, 3, 4]となります
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問