如何在Python中合并两个json字符串?

如何在Python中合并两个json字符串?,python,json,string,kazoo,Python,Json,String,Kazoo,我最近开始使用Python,并尝试将我的一个JSON字符串与现有的JSON字符串连接起来。我还与Zookeeper合作,因此在使用Python kazoo库时,我从Zookeeper节点获取现有的json字符串 # gets the data from zookeeper data, stat = zk.get(some_znode_path) jsonStringA = data.decode("utf-8") 如果我打印jsonStringA它会给我这样的结果- {"error_13959

我最近开始使用Python,并尝试将我的一个JSON字符串与现有的JSON字符串连接起来。我还与Zookeeper合作,因此在使用Python kazoo库时,我从Zookeeper节点获取现有的json字符串

# gets the data from zookeeper
data, stat = zk.get(some_znode_path)
jsonStringA = data.decode("utf-8")
如果我打印
jsonStringA
它会给我这样的结果-

{"error_1395946244342":"valueA","error_1395952003":"valueB"}
{u'error_1395946244342': u'valueA', u'error_1395952003': u'valueB'}
{"error_1395946244342":"valueA","error_1395952003":"valueB","error_1395952167":"Error Occured on machine h1 in datacenter dc3 on the step2 of process test"}
但是如果我打印json.loads(jsonString),它就会这样打印出来-

{"error_1395946244342":"valueA","error_1395952003":"valueB"}
{u'error_1395946244342': u'valueA', u'error_1395952003': u'valueB'}
{"error_1395946244342":"valueA","error_1395952003":"valueB","error_1395952167":"Error Occured on machine h1 in datacenter dc3 on the step2 of process test"}
这里
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"}
{u'error_1395946244342': u'valueA', u'error_1395952003': u'valueB'}
{"error_1395946244342":"valueA","error_1395952003":"valueB","error_1395952167":"Error Occured on machine h1 in datacenter dc3 on the step2 of process test"}

这可能吗?

合并是什么意思?JSON对象是键值数据结构。在这种情况下,键和值是什么?我认为您需要创建新目录并用旧数据填充它:

d = {}
d["new_key"] = jsonStringA[<key_that_you_did_not_mention_here>] + \ 
               jsonStringB["timestamp_in_ms"]
d={}
d[“新密钥”]=jsonStringA[]+\
jsonStringB[“时间戳单位为毫秒”]

合并方法显然取决于您。

您可以将两个json字符串加载到Python字典中,然后合并。只有当每个json字符串中都有唯一的键时,这才有效

import json

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

假设a和b是要合并的词典:

c = {key: value for (key, value) in (a.items() + b.items())}
要将字符串转换为python字典,请使用以下命令:

import json
my_dict = json.loads(json_str)

更新:使用字符串的完整代码:

# 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)
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))
但我必须说,一般来说,你试图做的并不是最佳实践。请阅读一些python字典


替代解决方案:

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

实际上,如果只使用一个数组来保存所有错误,就可以避免所有这些错误。

合并json对象相当简单,但在处理键冲突时有一些边缘情况。最大的问题是一个对象具有简单类型的值,而另一个对象具有复杂类型(数组或对象)。你必须决定如何实现这一点。当我们实现传递给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

如果您还想合并列表,或者在遇到特殊键的特定情况下,您可以在第一个案例之后添加另一个案例来检查列表。

从Python 3.5开始,您可以将两个DICT合并为:

merged = {**dictA, **dictB}
()

因此:


等。

要将键值对附加到json字符串,可以使用:
dictA.update(dictB)

对于您的情况,如下所示:

dictA = json.loads(jsonStringA)
dictB = json.loads('{"error_1395952167":"Error Occured on machine h1 in datacenter dc3 on the step2 of process test"}')

dictA.update(dictB)
jsonStringA = json.dumps(dictA)

请注意,键冲突将导致
dictB
中的值覆盖
dictA

您使用字符串还是字典?我给你的例子是正确的。我再次更新了问题。正如我最近开始使用Python一样,我不确定字典在这里的意思是什么。我已经更新了我的
jsonStringA
如何打印出来的问题。我想我需要附加的字符串是一个简单的字符串。我更新了我的答案。现在我使用纯json字符串作为输入。请仔细阅读,这样您就可以理解字符串和字典发生了什么。这现在是有意义的。。最后一个问题是,如何使
jsonStringB
的所有值都正确?因为我需要与变量中的所有值建立一个键值对。另外,请注意,这将通过用
b
中的值覆盖
a
中的值来无声地处理键冲突。请不要使用
dict(a,**b)
。这实际上是对
CPython
实现的滥用。而是使用
c=a.copy();c、 更新(b)
。在我的例子中,所有json字符串都有key:value对,它们都是字符串。我没有任何数组之类的东西。那就不用担心了,这段代码会像在这种情况下一样正常工作。最后一个问题是,在我的情况下,如何将json_string2作为键值对?因为我需要从变量中构造这个json字符串。有什么想法吗?啊,我想我误读了你的代码,我相信你的jsonString[AB]实际上是我代码的json_字符串[12]。我将编辑代码以反映该假设。如果存在嵌套字典,则此操作不起作用。请注意,字典解包将占用大量资源。请注意,这将通过用dictB中的值覆盖dictA中的值来静默处理键冲突。