Lid*_*dia 0 python recursion json python-2.x
我需要修改下面的json文件test.json:
{
"install": {
"site": {
"acls": {
"dns": {
"authorized_ports": ["53:tcp", "53:udp"]
}
},
"network": {
"clusters": {
"__ip_range_1__": {
"dhcpstart": "__ip__",
"dhcpend": "__ip__",
"adminip": "__ip__"
},
"__ip_range_2__": {
"dhcpstart": "__ip__",
"dhcpend": "__ip__",
"adminip": "__ip__"
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
以上是缩写,原始文件中还有很多条目。我每个站点都有几个这样的文件,因此__ip_range_x__每个文件都不同,每个 IP 也是如此。我需要为每个__ip_range_x__元素添加条目。新条目是interface_config存储在 mod.json 中的字典字典(如下):
{
"path": "{install}{site}{network}{clusters}{*}",
"install" : {
"site": {
"network": {
"clusters": {
"__iprange": {
"interface_config": {
"framesize": "1500",
"framesize_vm": "1500"
}
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我还需要在原始 json 文件的不同部分添加其他条目。
现在,我只是想遍历 test.json 中的所有元素。最终,我想为 test.json 中的每个元素构建一个路径,并将其与来自 mod.json 的路径匹配以修改 test.json。但是,我无法在原始文件中打印所有元素。我目前的代码:
import json
import pprint
def traverse(d, path=None):
if path is None:
path = []
for item,val in d.iteritems():
if isinstance(item, dict):
for k,v in item.iteritems():
print k
traverse(v)
elif isinstance(item, list):
for j in item:
(traverse(j))
else:
print item
if isinstance(val, dict):
for k,v in val.iteritems():
print k
traverse(v)
elif isinstance(val, list):
for j in val:
(traverse(j))
with open("test.json", "r") as jf:
data = json.load(jf)
traverse(data)
Run Code Online (Sandbox Code Playgroud)
上面的输出是:
{
"install": {
"site": {
"acls": {
"dns": {
"authorized_ports": ["53:tcp", "53:udp"]
}
},
"network": {
"clusters": {
"__ip_range_1__": {
"dhcpstart": "__ip__",
"dhcpend": "__ip__",
"adminip": "__ip__"
},
"__ip_range_2__": {
"dhcpstart": "__ip__",
"dhcpend": "__ip__",
"adminip": "__ip__"
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我的第一个iteritems电话是在错误的地方,但我无法理解递归......任何指针都表示赞赏。顺便说一句,我在 Python 2 上。
编辑
我试图处理的实际 json 比上面列出的要复杂。这是一个编辑过的版本:
{
"install": {
"site": {
"acls": {
"dns": {
"authorized_ports": ["53:tcp", "53:udp"]
}
},
"network": {
"clusters": {
"__ip_range_1__": {
"dhcpstart": "__ip__",
"dhcpend": "__ip__",
"adminip": "__ip__"
},
"__ip_range_2__": {
"dhcpstart": "__ip__",
"dhcpend": "__ip__",
"adminip": "__ip__"
}
}
}
}
}
"config": {
"ippool": [
{
"pool_name": "/ippool1",
"pool_description": "IP Pool1",
"ranges": [["__ip__", "__ip__"]]
},
{
"pool_name": "/ippool2",
"pool_description": "IP Pool2",
"ranges": [["__ip__", "__ip__"]]
}
],
"storage": [
{
"account": "/root",
"credentials": {
"account": "admin",
"service": "storage",
"user": "admin",
"password": "pass"
}
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
我修改了 Paul Panzer 的回答以包含如下列表:
def traverse(d, path=[]):
for k, v in d.iteritems():
yield path + [k], v
if isinstance(v, dict):
for k,v in traverse(v, path + [k]):
yield k,v
elif isinstance(v, list):
for k in v:
traverse(k, path + [])
Run Code Online (Sandbox Code Playgroud)
然而,上面没有打印 ippool 和存储列表中的元素。一旦遇到字典列表,由于某种原因不会遍历它。
这是您traverse例程的清理版本。它只是遍历一个嵌套的字典/列表;为清楚起见,我已经削减了所有其他内容。希望能帮助到你。
master = {
"install": {
"site": {
"acls": {
"dns": {
"authorized_ports": ["53:tcp", "53:udp"]
}
},
"network": {
"clusters": {
"__ip_range_1__": {
"dhcpstart": "__ip__",
"dhcpend": "__ip__",
"adminip": "__ip__"
},
"__ip_range_2__": {
"dhcpstart": "__ip__",
"dhcpend": "__ip__",
"adminip": "__ip__"
}
}
}
}
},
"config": {
"ippool": [
{
"pool_name": "/ippool1",
"pool_description": "IP Pool1",
"ranges": [["__ip__", "__ip__"]]
},
{
"pool_name": "/ippool2",
"pool_description": "IP Pool2",
"ranges": [["__ip__", "__ip__"]]
}
],
"storage": [
{
"account": "/root",
"credentials": {
"account": "admin",
"service": "storage",
"user": "admin",
"password": "pass"
}
}
]
}
}
def traverse(dict_or_list, path=[]):
if isinstance(dict_or_list, dict):
iterator = dict_or_list.iteritems()
else:
iterator = enumerate(dict_or_list)
for k, v in iterator:
yield path + [k], v
if isinstance(v, (dict, list)):
for k, v in traverse(v, path + [k]):
yield k, v
for path, node in traverse(master):
print path
Run Code Online (Sandbox Code Playgroud)
输出:
['config']
['config', 'ippool']
['config', 'ippool', 0]
['config', 'ippool', 0, 'ranges']
['config', 'ippool', 0, 'ranges', 0]
['config', 'ippool', 0, 'ranges', 0, 0]
['config', 'ippool', 0, 'ranges', 0, 1]
['config', 'ippool', 0, 'pool_name']
['config', 'ippool', 0, 'pool_description']
['config', 'ippool', 1]
['config', 'ippool', 1, 'ranges']
['config', 'ippool', 1, 'ranges', 0]
['config', 'ippool', 1, 'ranges', 0, 0]
['config', 'ippool', 1, 'ranges', 0, 1]
['config', 'ippool', 1, 'pool_name']
['config', 'ippool', 1, 'pool_description']
['config', 'storage']
['config', 'storage', 0]
['config', 'storage', 0, 'credentials']
['config', 'storage', 0, 'credentials', 'account']
['config', 'storage', 0, 'credentials', 'password']
['config', 'storage', 0, 'credentials', 'user']
['config', 'storage', 0, 'credentials', 'service']
['config', 'storage', 0, 'account']
['install']
['install', 'site']
['install', 'site', 'acls']
['install', 'site', 'acls', 'dns']
['install', 'site', 'acls', 'dns', 'authorized_ports']
['install', 'site', 'acls', 'dns', 'authorized_ports', 0]
['install', 'site', 'acls', 'dns', 'authorized_ports', 1]
['install', 'site', 'network']
['install', 'site', 'network', 'clusters']
['install', 'site', 'network', 'clusters', '__ip_range_2__']
['install', 'site', 'network', 'clusters', '__ip_range_2__', 'dhcpend']
['install', 'site', 'network', 'clusters', '__ip_range_2__', 'adminip']
['install', 'site', 'network', 'clusters', '__ip_range_2__', 'dhcpstart']
['install', 'site', 'network', 'clusters', '__ip_range_1__']
['install', 'site', 'network', 'clusters', '__ip_range_1__', 'dhcpend']
['install', 'site', 'network', 'clusters', '__ip_range_1__', 'adminip']
['install', 'site', 'network', 'clusters', '__ip_range_1__', 'dhcpstart']
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5288 次 |
| 最近记录: |