How to merge two json string in Python?
我最近开始使用python,并尝试将我的一个JSON字符串与现有的JSON字符串连接起来。我还与ZooKeeper一起工作,因此在使用python-kazoo库时,从ZooKeeper节点获取现有的JSON字符串。
1 2 3 | # gets the data from zookeeper data, stat = zk.get(some_znode_path) jsonStringA = data.decode("utf-8") |
如果我打印
1 | {"error_1395946244342":"valueA","error_1395952003":"valueB"} |
但是如果我这样做,那么它就会像这样打印出来。-
1 | {u'error_1395946244342': u'valueA', u'error_1395952003': u'valueB'} |
这里,
下面是我的python代码-
1 2 3 4 5 6 7 8 9 10 | # 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" |
我现有的
1 | {"error_1395946244342":"valueA","error_1395952003":"valueB"} |
现在我需要在
1 | "timestamp_in_ms":"Error Occured on machine"+host_info+" in datacenter"+ local_dc +" on the"+ step +" of process"+ c +" |
所以简而言之,我需要合并下面的键值对-
1 | "error_1395952167":"Error Occured on machine h1 in datacenter dc3 on the step2 of process test" |
所以最终的json字符串将如下所示-
1 | {"error_1395946244342":"valueA","error_1395952003":"valueB","error_1395952167":"Error Occured on machine h1 in datacenter dc3 on the step2 of process test"} |
这可以吗?
假设A和B是要合并的字典:
1 | c = {key: value for (key, value) in (a.items() + b.items())} |
要将字符串转换为python字典,请使用以下方法:
1 2 | import json my_dict = json.loads(json_str) |
更新:使用字符串的完整代码:
1 2 3 4 5 6 7 8 | # test cases for jsonStringA and jsonStringB according to your data input jsonStringA = '{"error_1395946244342":"valueA","error_1395952003":"valueB <div class="suo-content">[collapse title=""]<ul><li>不好意思弄混了。我现在更新了我的问题,所以现在应该有意义了。</li><li>你用的是字符串还是字典?我给你的例子是正确的。</li><li>我又更新了问题。正如我最近从python开始的,所以不确定dictionary在这里是什么意思。我已经更新了我的<wyn>jsonStringA</wyn>如何打印出来的问题。我想需要附加的字符串是一个简单的字符串。</li><li>我更新了我的答案。现在我使用普通的JSON字符串作为输入。请仔细阅读,以便您了解字符串和字典的情况。</li><li>这很有道理……最后一个问题是,如何正确地使用<wyn>jsonStringB</wyn>的所有值?因为我需要与变量中的所有值进行键值配对。</li><li>请参见更新的代码。%s就地添加一个字符串类型的参数,%d添加一个整数。所有参数都在末尾的元组中。(a,b,c,…)</li><li>希望有帮助,如果您对结果满意,请将问题标记为已回答。</li><li>我一定会的。但是你能告诉我这个方法有什么问题吗?为什么你说这不是正确的方法?只是想知道。</li><li>除了时间戳提供的优先级之外,这些键似乎没有太大的重要性。因此维护字典比维护数组要复杂得多。尤其是如果您有所有这些字符串转换/json解码。除非您在后面的阶段需要这个数据结构,上面的代码示例中没有显示。就个人而言,在编码方面,我喜欢"保持简单愚蠢"的想法,当然,我最喜欢的是"少即多":)</li><li>谢谢你的帮助。是的,它们有些用处。我将把这个JSON字符串写回ZooKeKER,然后我有一个Java程序运行,它保持对那个节点的监视,只提取最新的时间戳。不管怎样,告诉我一件事:假设这个方法<wyn>get_my_value_as_string_from_somewhere()</wyn>返回空字符串,那么我能用new_error_str生成正确的JSON字符串吗?</li><li>不,不能将空字符串解码为JSON。你可以做一些类似于<wyn>jsonStringA = get_my_value_as_string_from_somewhere() or '{}'</wyn>的事情。是有效的JSON对象。</li><li>有道理。。但在这种情况下,如何检查<wyn>jsonStringA</wyn>是否为空,然后将<wyn>jsonStringA</wyn>分配给<wyn>{}</wyn>?否则保持原样。这可以吗?</li><li>你在我最后的评论中看到的就是你想做的。他们Python道:)</li></ul>[/collapse]</div><hr><P>您可以将这两个JSON字符串加载到Python字典中,然后进行组合。只有在每个JSON字符串中都有唯一的键时,这才有效。</P>[cc lang="python"] import json a = json.loads(jsonStringA) b = json.loads(jsonStringB) c = dict(a.items() + b.items()) # or c = dict(a, **b) |
从python 3.5开始,可以将两个dict合并为:
1 | merged = {**dictA, **dictB} |
(https://www.python.org/dev/peps/pep-0448/)
所以:
1 2 | jsonMerged = {**json.loads(jsonStringA), **json.loads(jsonStringB)} asString = json.dumps(jsonMerged) |
等。
Merging json objects is fairly straight forward but has a few edge cases when dealing with key collisions. The biggest issues have to do with one object having a value of a simple type and the other having a complex type (Array or Object). You have to decide how you want to implement that. Our choice when we implemented this for json passed to chef-solo was to merge Objects and use the first source Object's value in all other cases.
This was our solution:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 |
如果要合并列表,也可以在第一个案例之后添加另一个案例,或者在遇到特殊键时检查特定案例。
合并是什么意思?JSON对象是键值数据结构。在这种情况下,键和值是什么?我认为您需要创建新目录并用旧数据填充它:
1 2 3 | d = {} d["new_key"] = jsonStringA[<key_that_you_did_not_mention_here>] + \ jsonStringB["timestamp_in_ms"] |
合并方法显然取决于您。