操作包含JSON字符串字典的JSON文件

huangapple go评论67阅读模式
英文:

Manipulating a json file containing a dict of json string

问题

我有一个包含字符串:字符串键值对的json文件

我尝试首先使用json.load加载文件然后更新字典但是当我将更新后的字典转储时我丢失了键无法弄清楚如何更新值

我正在尝试将**sampleID**的值更新为其他内容并写回同一文件

```python
{"key":"{\"url\":\"DEFAULT\",\"id\":\"tzz22s6a\",\"sampleID\":\"jahsdioadhao\",\"isPassRequired\":false,\"isKeyRequired\":true,\"materialType\":\"SATIN\",\"clothType\":\"DEFAULT\"}"}

到目前为止,我尝试了以下方法,它可以更新sampleId的值,但是文件的格式已经改变,并且我丢失了键,即**"key"**。

with open(os.path.join(root, file_name)) as jsonFile:
    d = json.load(jsonFile)
    for values in d:
        data = json.loads(d[values])
        data['sampleID'] = 'newValue'

with open(os.path.join(root, file_name), 'w') as jsonFile:
    json.dump(data, jsonFile, indent=4)

<details>
<summary>英文:</summary>

I have a json file consisting of a dict of String:String

I tried to first load the file using json.load and then update the dict but when I dump the updated dict I lose the key. Unable to figure out how to update a value.

I&#39;m trying to update the value of **sampleID** to something else and write back to the same file.

{"key":"{&quot;url&quot;:&quot;DEFAULT&quot;,&quot;id&quot;:&quot;tzz22s6a&quot;,&quot;sampleID&quot;:&quot;jahsdioadhao&quot;,&quot;isPassRequired&quot;:false,&quot;isKeyRequired&quot;:true,&quot;materialType&quot;:&quot;SATIN&quot;,&quot;clothType&quot;:&quot;DEFAULT&quot;}"}


what I tried so far, which updates the value of sampleId but the format of the file is changed and also I loose the key i.e., **&quot;key&quot;**

with open(os.path.join(root, file_name)) as jsonFile:
d = json.load(jsonFile)
for values in d:
data = json.loads(d[values])
data['sampleID'] = 'newValue'

with open(os.path.join(root, file_name), 'w') as jsonFile:
json.dump(data, jsonFile, indent=4)


</details>


# 答案1
**得分**: 1

需要将`data`转换回字符串,并将其插入回原始字典中。

```python
with open(os.path.join(root, file_name)) as jsonFile:
    d = json.load(jsonFile)
    for k in d:
        data = json.loads(d[k])
        data['sampleID'] = 'newValue'
        d[k] = json.dumps(data)

with open(os.path.join(root, file_name), 'w') as jsonFile:
    json.dump(d, jsonFile, indent=4)

输出

{"key": "{\"url\": \"DEFAULT\", \"id\": \"tzz22s6a\", \"sampleID\": \"newValue\", \"isPassRequired\": false, \"isKeyRequired\": true, \"materialType\": \"SATIN\", \"clothType\": \"DEFAULT\"}"}

如果您不真正需要以这种格式保存`json`,将`d[k] = json.dumps(data)` 替换为 `d[k] = data` 也会给您一个有效的 `json`。
英文:

You need to convert data back to string and insert it back to the original dictionary

with open(os.path.join(root, file_name)) as jsonFile:
    d = json.load(jsonFile)
    for k in d:
        data = json.loads(d[k])
        data[&#39;sampleID&#39;] = &#39;newValue&#39;
        d[k] = json.dumps(data)

with open(os.path.join(root, file_name), &#39;w&#39;) as jsonFile:
    json.dump(d, jsonFile, indent=4)

Output

{&quot;key&quot;: &quot;{\&quot;url\&quot;: \&quot;DEFAULT\&quot;, \&quot;id\&quot;: \&quot;tzz22s6a\&quot;, \&quot;sampleID\&quot;: \&quot;newValue\&quot;, \&quot;isPassRequired\&quot;: false, \&quot;isKeyRequired\&quot;: true, \&quot;materialType\&quot;: \&quot;SATIN\&quot;, \&quot;clothType\&quot;: \&quot;DEFAULT\&quot;}&quot;}

If you don't really need the json in this format, replacing d[k] = json.dumps(data) with d[k] = data will also give you a valid json.

答案2

得分: 1

看起来你提供的示例 JSON 中,嵌套的 JSON 对象没有正确序列化。

要更新嵌套键,你应该在 d 对象内部进行修改,或者将 key 重新赋值为更新后的 data JSON 对象,如下所示:

with open(os.path.join(root, file_name)) as jsonFile:
    d = json.load(jsonFile)
    for key in d:
        # 如果输入的 JSON 是有效的,你不需要在下面的行再次加载它,但在你的示例中它是无效的。
        data = json.loads(d[key])
        data['sampleID'] = 'newValue'
        # 将 "key" 在 d 中设置为更新后的数据字典。
        d[key] = data

附加说明:

  • d 的迭代器将循环遍历键,所以我将其更改为 for key in d 以使其更清晰。
  • 你粘贴的示例中的嵌套 JSON 由于反斜杠字符而不是有效的 JSON,所以为了复制你的代码,我做了以下更改:
import json
import re

data = {"key": "{\"url\":\"DEFAULT\",\"id\":\"tzz22s6a\",\"sampleID\":\"jahsdioadhao\",\"isPassRequired\":false,\"isKeyRequired\":true,\"materialType\":\"SATIN\",\"clothType\":\"DEFAULT\"}"}

# 创建正则表达式编译器
pattern = re.compile(r"\\\"")

# 将模式中的字符替换为空字符串 `""`,并在 data["key"] 上进行替换
pattern.sub("", data["key"])

# 将 data["key"] 直接设置为 JSON 字符串的字典。
data["key"] = json.loads(data["key"])

# 替换 "key" 中的 "sampleID" 值
data["key"]["sampleID"] = "newValue"

# 这将产生以下结果:
{"key": {"url": "DEFAULT", "id": "tzz22s6a", "sampleID": "newValue", "isPassRequired": false, "isKeyRequired": true, "materialType": "SATIN", "clothType": "DEFAULT"}}

希望这对你有所帮助。

英文:

It looks like your nested json object isn't getting serialised properly from the sample JSON you provided.

To update the nested key you should modify it either in place inside the d object, or reassign key to the updated data JSON obj such as:

with open(os.path.join(root, file_name)) as jsonFile:
    d = json.load(jsonFile)
    for key in d:
        # You shouldn&#39;t need to load this again on the line below if the input json is valid but in your example it is not.
        data = json.loads(d[key])
        data[&#39;sampleID&#39;] = &#39;newValue&#39;
        # Set &quot;key&quot; in d to be the updated data dict.
        d[key] = data

Additional points:

  • The iterator of d will loop through the keys so I changed it to for key in d to make it clearer.
  • Your nested JSON in the pasted example isn't value due to the backslash characters so to reproduce your code I did this:
import json
import re

data = {&quot;key&quot;:&quot;{\&quot;url\&quot;:\&quot;DEFAULT\&quot;,\&quot;id\&quot;:\&quot;tzz22s6a\&quot;,\&quot;sampleID\&quot;:\&quot;jahsdioadhao\&quot;,\&quot;isPassRequired\&quot;:false,\&quot;isKeyRequired\&quot;:true,\&quot;materialType\&quot;:\&quot;SATIN\&quot;,\&quot;clothType\&quot;:\&quot;DEFAULT\&quot;}&quot;}

# Create a regex compiler
pattern = re.compile(r&quot;\\&quot;)

# Sub the characters in pattern with empty string `&quot;&quot;` in place on data[&quot;key&quot;]
pattern.sub(&quot;&quot;, data[&quot;key&quot;])

# Set data[&quot;key&quot;] in place to be the dict of the json string.
data[&quot;key&quot;] = json.loads(data[&quot;key&quot;])

# Replace the value of &quot;sampleID&quot; in &quot;key&quot;
data[&quot;key&quot;][&quot;sampleID&quot;] = &quot;newValue&quot;

# which produces
{&#39;key&#39;: {&#39;url&#39;: &#39;DEFAULT&#39;,
  &#39;id&#39;: &#39;tzz22s6a&#39;,
  &#39;sampleID&#39;: &#39;newValue&#39;,
  &#39;isPassRequired&#39;: False,
  &#39;isKeyRequired&#39;: True,
  &#39;materialType&#39;: &#39;SATIN&#39;,
  &#39;clothType&#39;: &#39;DEFAULT&#39;}}

huangapple
  • 本文由 发表于 2023年6月1日 15:39:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76379662.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定