英文:
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'm trying to update the value of **sampleID** to something else and write back to the same file.
{"key":"{"url":"DEFAULT","id":"tzz22s6a","sampleID":"jahsdioadhao","isPassRequired":false,"isKeyRequired":true,"materialType":"SATIN","clothType":"DEFAULT"}"}
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., **"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>
# 答案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['sampleID'] = 'newValue'
d[k] = json.dumps(data)
with open(os.path.join(root, file_name), 'w') as jsonFile:
json.dump(d, jsonFile, indent=4)
Output
{"key": "{\"url\": \"DEFAULT\", \"id\": \"tzz22s6a\", \"sampleID\": \"newValue\", \"isPassRequired\": false, \"isKeyRequired\": true, \"materialType\": \"SATIN\", \"clothType\": \"DEFAULT\"}"}
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'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['sampleID'] = 'newValue'
# Set "key" 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 tofor 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 = {"key":"{\"url\":\"DEFAULT\",\"id\":\"tzz22s6a\",\"sampleID\":\"jahsdioadhao\",\"isPassRequired\":false,\"isKeyRequired\":true,\"materialType\":\"SATIN\",\"clothType\":\"DEFAULT\"}"}
# Create a regex compiler
pattern = re.compile(r"\\")
# Sub the characters in pattern with empty string `""` in place on data["key"]
pattern.sub("", data["key"])
# Set data["key"] in place to be the dict of the json string.
data["key"] = json.loads(data["key"])
# Replace the value of "sampleID" in "key"
data["key"]["sampleID"] = "newValue"
# which produces
{'key': {'url': 'DEFAULT',
'id': 'tzz22s6a',
'sampleID': 'newValue',
'isPassRequired': False,
'isKeyRequired': True,
'materialType': 'SATIN',
'clothType': 'DEFAULT'}}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论