它可能是痛苦的導航和修改從JSON對象派生的深層嵌套對象。在Functions that help to understand json(dict) structure我發佈了允許您瀏覽這些對象的代碼。請閱讀該答案中的解釋。在這個答案中,我將展示如何使用該代碼修改這些對象中的字典鍵。
簡而言之,find_key
是一個遞歸生成器,它將查找具有給定名稱的所有鍵。您可以使用next
函數獲取第一個(或唯一)匹配的名稱。或者在for
循環中調用find_key
,如果您需要使用具有相同名稱的多個密鑰。
find_key
產生的每個值是dict
鍵的列表,並且列表索引需要達到期望的鍵。
from json import dumps
def find_key(obj, key):
if isinstance(obj, dict):
yield from iter_dict(obj, key, [])
elif isinstance(obj, list):
yield from iter_list(obj, key, [])
def iter_dict(d, key, indices):
for k, v in d.items():
if k == key:
yield indices + [k], v
if isinstance(v, dict):
yield from iter_dict(v, key, indices + [k])
elif isinstance(v, list):
yield from iter_list(v, key, indices + [k])
def iter_list(seq, key, indices):
for k, v in enumerate(seq):
if isinstance(v, dict):
yield from iter_dict(v, key, indices + [k])
elif isinstance(v, list):
yield from iter_list(v, key, indices + [k])
results = {
"Game": 12345,
"stats": [
{
"detail": [
{
"goals": 4,
"refs": {
"number": 0
}
}
]
}
]
}
# Change oldkey to newkey
oldkey, newkey = 'goals', 'goals_against'
# Find the first occurrence of the oldkey
seq, val = next(find_key(results, oldkey))
print('seq:', seq, 'val:', val)
# Get the object that contains the oldkey
obj = results
for k in seq[:-1]:
obj = obj[k]
# Change the key
obj[newkey] = obj.pop(oldkey)
print(dumps(results, indent=4))
輸出
seq: ['stats', 0, 'detail', 0, 'goals'] val: 4
{
"Game": 12345,
"stats": [
{
"detail": [
{
"refs": {
"number": 0
},
"goals_against": 4
}
]
}
]
}
的[重命名字典鍵]可能的複製(https://stackoverflow.com/questions/16475384/rename-a-dictionary-key) – DJV
@DJV它有點不同,因爲我試圖更新的JSon對象中的密鑰是深嵌套的,有時它需要添加下一個節點的索引,例如[0] – jquyl
您可以使用我發佈的代碼作爲[此答案] (http://stackoverflow.com/q/41777880/4014959)爲此任務。我幾乎將這個問題作爲該問題的一個重複來解決,但我認爲它有不同之處,因此它應該有自己的答案,所以我會在幾分鐘後發佈一些代碼。 –