gpt4 book ai didi

python - 查找并修改Python嵌套字典(键,值)

转载 作者:太空宇宙 更新时间:2023-11-03 16:19:57 27 4
gpt4 key购买 nike

我有一个需要更新的 json 文件。我将其转换为 python 字典(嵌套)来更新它。这是输入,但它可以是任何部门。我确信有更好的方法来做到这一点,但我不知道。

最终我希望除了更新之外还能够执行创建/删除操作。

<小时/>

这是脚本和输入文件。

# Now find TARGET value in nested key value chain

# Replace old value with NEWVALUE

import json
from pprint import pprint
d1 = open('jinputstack.json', 'r')
d1 = json.load(d1)

def traverse(obj, path=None, callback=None):
"""
Traverse Python object structure, calling a callback function for every element in the structure,
and inserting the return value of the callback as the new value.
"""
if path is None:
path = []

if isinstance(obj, dict):
value = {k: traverse(v, path + [k], callback)
for k, v in obj.items()}
elif isinstance(obj, list):
value = [traverse(elem, path + [[]], callback)
for elem in obj]
else:
value = obj

if callback is None:
# print("Starting value Found-----------------------------------------------------")
print(value)
return value

else:
print(path, value)
return callback(path, value)


def traverse_modify(obj, target_path, action):
"""
Traverses any arbitrary object structure and performs the given action on the value,
replacing the node with the
action's return value.
"""
target_path = to_path(target_path)
pprint(value)
pprint(target_path)

def transformer(path, value):
if path == target_path:
print(action)
d2 = data["groups"][0]["properties"][1]["value"]["data"][2]["object"]["name"].update(action)
return d2

else:
return value

return traverse(obj, callback=transformer)


def to_path(path):
"""
Helper function, converting path strings into path lists.
>>> to_path('foo')
['foo']
>>> to_path('foo.bar')
['foo', 'bar']
>>> to_path('foo.bar[]')
['foo', 'bar', []]
"""
if isinstance(path, list):
return path # already in list format

def _iter_path(path):

#pprint(path.split)

for parts in path.split('[]'):
for part in parts.strip('.').split('.'):
yield part
yield []

return list(_iter_path(path))[:-1]

def updateit(newvalue):

data["groups"][0]["properties"][1]["value"]["data"][2]["object"]["name"] = newvalue
print(data["groups"][0]["properties"][1]["value"]["data"][2]["object"]["name"])
return data["groups"][0]["properties"][1]["value"]["data"][2]["object"]["name"]

traverse_modify(d1, d1["groups"][0]["properties"][1]["value"]["data"][1]["object"]["name"], updateit("XXXXXXXXXXXXXX"))

json_data = json.dumps(data)

f = open("jinputstack.json","w")
f.write(json_data)
f.close()
<小时/>
jinputstack.json = {
"groups": [
{
"name": "group1",
"properties": [
{
"name": "Test-Key-String",
"value": {
"type": "String",
"encoding": "utf-8",
"data": "value1"
}
},
{
"name": "Test-Key-ValueArray",
"value": {
"type": "ValueArray",
"data": [
{
"data": true
},
{
"type": "Blob",
"object": {
"name": "John Su",
"age": 25,
"salary": 104000.45,
"married": false,
"gender": "Male"
}
}
]
}
}
],
"groups": [
{
"name": "group-child",
"properties": [
{
"name": "Test-Key-String"
},
{
"name": "Test-Key-List",
"value": {
"type": "List",
"data": [
"String1",
"String2",
"String3"
]
}
}
]
}
]
},
{
"name": "group2",
"properties": [
{
"name": "Test-Key2-String",
"value": {
"type": "String",
"encoding": "utf-8",
"data": "value2"
}
},
{
"name": "MicroBox"
}
]
}
]
}

感谢原作者:Vincent Driessen

最佳答案

我认为最好的方法是将 Json 对象转换为 XML 并使用 ElementTree 和 XPath 来解析和修改您的对象。如果需要,稍后您可以恢复为 Json:

import json
from xmljson import parker
from lxml.etree import Element

dataxml = parker.etree(datajson, root=Element('root'))
print(dataxml.find('.//data//name').text) # John Su
dataxml.find('.//data//name').text = "Joan d'Arc"
print(dataxml.find('.//data//name').text) # Joan d'Arc
print(json.dumps(parker.data(dataxml)))

有一些包直接在 Json 字符串上执行类似 XPath 的操作。其中之一,jsonpath-rw 改变了语法。我更喜欢坚持使用标准 XPath 语法。

from jsonpath_rw import jsonpath, parse

expr = parse('$..data..name') # Notice that . is now $ and / is now .
# Confusing enough?
expr.find(datajson)[0] = 'yyyy'
print(expr.find(datajson)[0].value) # John Su

另一个 xjpath 非常简单,也许更容易学习,与您现在所做的相比并没有太大区别。

import xjpath

xj = xjpath.XJPath(datajson)
print(xj['groups.@0.properties.@1.value.data.@1.object.name'])

# Not much different than your code:
print(data["groups"][0]["properties"][1]["value"]["data"][1]["object"]["name"])

我希望这会有所帮助。

关于python - 查找并修改Python嵌套字典(键,值),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38577049/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com