web-dev-qa-db-ja.com

Pythonで2つのjson文字列をマージする方法は?

私は最近Pythonで作業を開始しました。JSON文字列の1つを既存のJSON文字列と連結しようとしています。 Python kazoo library。

_# gets the data from zookeeper
data, stat = zk.get(some_znode_path)
jsonStringA = data.decode("utf-8")
_

jsonStringAを印刷すると、次のようになります-

_{"error_1395946244342":"valueA","error_1395952003":"valueB"}
_

しかし、print json.loads(jsonString)を実行すると、次のように出力されます-

_{u'error_1395946244342': u'valueA', u'error_1395952003': u'valueB'}
_

ここで、jsonStringAには既存のJSON文字列が含まれます。これで、既存のjsonStringAに追加する必要がある別のキーと値のペアがあります-

以下は私のPythonコード-

_# gets the data from zookeeper
data, stat = zk.get(some_znode_path)
jsonStringA = data.decode("utf-8")

timestamp_in_ms = "error_"+str(int(round(time.time() * 1000)))
node = "/pp/tf/test/v1"
a,b,c,d = node.split("/")[1:]
Host_info = "h1"
local_dc = "dc3"
step = "step2"
_

私の既存のjsonStringAは、zookeeperから抽出した後、このようになります-

_{"error_1395946244342":"valueA","error_1395952003":"valueB"}
_

次に、このキーと値のペアをjsonStringAに追加する必要があります-

_"timestamp_in_ms":"Error Occured on machine "+Host_info+" in datacenter "+ local_dc +" on the "+ step +" of process "+ c +"
_

要するに、キーと値のペアの下にマージする必要があります-

_"error_1395952167":"Error Occured on machine h1 in datacenter dc3 on the step2 of process test"
_

最終的なJSON文字列は次のようになります-

_{"error_1395946244342":"valueA","error_1395952003":"valueB","error_1395952167":"Error Occured on machine h1 in datacenter dc3 on the step2 of process test"}
_

これは可能ですか?

15
user2467545

Aとbがマージする辞書であると仮定します。

c = {key: value for (key, value) in (a.items() + b.items())}

文字列をpython辞書に変換するには、次を使用します。

import json
my_dict = json.loads(json_str)

更新:stringsを使用した完全なコード

# test cases for jsonStringA and jsonStringB according to your data input
jsonStringA = '{"error_1395946244342":"valueA","error_1395952003":"valueB"}'
jsonStringB = '{"error_%d":"Error Occured on machine %s in datacenter %s on the %s of process %s"}' % (timestamp_number, Host_info, local_dc, step, c)

# now we have two json STRINGS
import json
dictA = json.loads(jsonStringA)
dictB = json.loads(jsonStringB)

merged_dict = {key: value for (key, value) in (dictA.items() + dictB.items())}

# string dump of the merged dict
jsonString_merged = json.dumps(merged_dict)

しかし、私は一般的にあなたがやろうとしていることはベストプラクティスではないと言わざるを得ません。 python辞書。


代替ソリューション:

jsonStringA = get_my_value_as_string_from_somewhere()
errors_dict = json.loads(jsonStringA)

new_error_str = "Error Ocurred in datacenter %s blah for step %s blah" % (datacenter, step)
new_error_key = "error_%d" % (timestamp_number)

errors_dict[new_error_key] = new_error_str

# and if I want to export it somewhere I use the following
write_my_dict_to_a_file_as_string(json.dumps(errors_dict))

実際、すべてのエラーを保持するために配列を使用するだけであれば、これらすべてを回避できます。

21
Vame

Python 3.5の時点で、2つのディクテーションをマージできます:

merged = {**dictA, **dictB}

https://www.python.org/dev/peps/pep-0448/

そう:

jsonMerged = {**json.loads(jsonStringA), **json.loads(jsonStringB)}
asString = json.dumps(jsonMerged)

等.

6
P i

両方のjson文字列をPython Dictionariesにロードしてから結合できます。これは、各json文字列に一意のキーがある場合にのみ機能します。

    import json

    a = json.loads(jsonStringA)
    b = json.loads(jsonStringB)
    c = dict(a.items() + b.items())
    # or c =  dict(a, **b)
6
theclaymethod

Jsonオブジェクトのマージはかなり簡単ですが、キーの衝突を処理する際にEdgeのケースがいくつかあります。最大の問題は、1つのオブジェクトが単純型の値を持ち、もう1つのオブジェクトが複雑な型(配列またはオブジェクト)を持つことに関係しています。それをどのように実装するかを決める必要があります。 chef-soloに渡されたjsonにこれを実装したときの選択は、オブジェクトをマージし、他のすべての場合に最初のソースオブジェクトの値を使用することでした。

これが私たちのソリューションでした:

from collections import Mapping
import json


original = json.loads(jsonStringA)
addition = json.loads(jsonStringB)

for key, value in addition.iteritems():
    if key in original:
        original_value = original[key]
        if isinstance(value, Mapping) and isinstance(original_value, Mapping):
            merge_dicts(original_value, value)
        Elif not (isinstance(value, Mapping) or 
                  isinstance(original_value, Mapping)):
            original[key] = value
        else:
            raise ValueError('Attempting to merge {} with value {}'.format(
                key, original_value))
    else:
        original[key] = value

最初のケースの後に別のケースを追加して、リストをマージする場合、または特殊キーが検出された特定のケースのリストを確認することもできます。

1
bschlueter

マージとはどういう意味ですか? JSONオブジェクトはキーと値のデータ構造です。この場合のキーと値は何ですか?新しいディレクトリを作成し、古いデータを格納する必要があると思います。

d = {}
d["new_key"] = jsonStringA[<key_that_you_did_not_mention_here>] + \ 
               jsonStringB["timestamp_in_ms"]

マージ方法は明らかにあなた次第です。

0
Vitaly Isaev