Python 如何展平字典';它只比3级深
假设你有这本字典Python 如何展平字典';它只比3级深,python,json,nested,flatten,Python,Json,Nested,Flatten,假设你有这本字典 { "alpha": "one", "beta": { "beta1": "two", "beta2": "second two" }, "gamma": { "delta": { "delta1": "three", "delta2": "second three" }, "epsilon": {
{
"alpha": "one",
"beta": {
"beta1": "two",
"beta2": "second two"
},
"gamma": {
"delta": {
"delta1": "three",
"delta2": "second three"
},
"epsilon": {
"zeta": {
"zeta1": "four",
"zeta2": "second four"
},
"epsilon1": "five",
"epsilon2": "second five"
}
}
}
并且您希望每三个(或更深层)嵌套字典都被展平。这样的输出
{
"alpha": "one",
"beta": {
"beta1": "two",
"beta2": "second two"
},
"gamma": {
"delta": {
"delta1": "three",
"delta2": "second three"
},
"epsilon": {
"zeta.zeta1": "four",
"zeta.zeta2": "second four",
"epsilon1": "five",
"epsilon2": "second five"
}
}
}
如何做到这一点
字典的标记和结构是动态的(我想重构具有不同结构的多个字典,但每三个嵌套字典都有一条硬线)
我知道我可以循环遍历每个值,但是我怎么知道何时到达第三个嵌套字典
def loopDict(d):
for k, v in d.iteritems():
if type(v) is dict:
loopDict(v)
else:
print "{0} : {1}".format(k, v)
另外,我可以使用flatte_json
模块展平每一本字典我修复了它
对于那些看这个的人,我最终用这种方式修复了它
xmldict={yourdictionary}
for k, v in xmldict.items():
if isinstance(v, dict):
for ke, va in v.items():
if isinstance(va, dict):
for key, val in va.items():
if isinstance(val, dict):
for key1, val1 in val.items():
if isinstance(val1, dict):
xmldict[k][ke][key] = flatten(v)
可以根据深度添加或删除for循环
(通常有一个更简洁的递归函数可以为您实现这一点)我修复了这个问题,但您更快了!不过,我也分享我的答案,也许它会有用
d={
“阿尔法”:“一”,
“测试版”:{
“beta1”:“两个”,
“beta2”:“第二个2”
},
“伽马”:{
“三角洲”:{
“三角洲1号”:“三号”,
“delta2”:“第二个三”
},
“ε”:{
“泽塔”:{
“zeta1”:“四个”,
“zeta2”:“第二个四”
},
“ε1”:“五”,
“ε2”:“第二个五”
}
}
}
def展平指令(d):
def items():
对于键,d.items()中的值:
如果isinstance(值,dict):
对于子键,在展平dict(value).items()中的子值:
屈服键+“+”子键,子值
其他:
屈服键、屈服值
返回dict(items())
def loopDict(d,深度):
对于d.项()中的k,v:
如果存在(v,dict):
如果深度>0:
d[k]=变平(v)
如果深度可以使用递归:
data = {'alpha': 'one', 'beta': {'beta1': 'two', 'beta2': 'second two'}, 'gamma': {'delta': {'delta1': 'three', 'delta2': 'second three'}, 'epsilon': {'zeta': {'zeta1': 'four', 'zeta2': 'second four'}, 'epsilon1': 'five', 'epsilon2': 'second five'}}}
def flatten(d, c = [], l = 1):
for a, b in d.items():
if not isinstance(b, dict):
yield a if l < 3 else '.'.join(c+[a]), b
else:
if l > 2:
yield from flatten(b, c=c+[a] if l > 2 else c, l=l+1)
else:
yield (a, list(flatten(b, c=c+[a] if l > 2 else c, l=l+1)))
def walk(d):
return {a:b if not isinstance(b, list) else walk(b) for a, b in d}
输出:
{
"alpha": "one",
"beta": {
"beta1": "two",
"beta2": "second two"
},
"gamma": {
"delta": {
"delta1": "three",
"delta2": "second three"
},
"epsilon": {
"zeta.zeta1": "four",
"zeta.zeta2": "second four",
"epsilon1": "five",
"epsilon2": "second five"
}
}
}
最简单的方法是将此过程分为两步。在输入字典上循环到所需的目标深度。然后在最里面的字典上调用展平函数:
def flatten(d):
for key, value in list(d.items()):
if isinstance(value, dict):
del d[key]
for subkey, subvalue in value.items():
newkey = key + '.' + subkey
d[newkey] = subvalue
for v1 in input_dict.values():
if isinstance(v1, dict):
for v2 in v1.values():
if isinstance(v2, dict):
flatten(v2)
这将产生:
{'alpha': 'one',
'beta': {'beta1': 'two', 'beta2': 'second two'},
'gamma': {'delta': {'delta1': 'three', 'delta2': 'second three'},
'epsilon': {'epsilon1': 'five',
'epsilon2': 'second five',
'zeta.zeta1': 'four',
'zeta.zeta2': 'second four'}}}
如果需要更一般的方法,可以使其中一个或两个步骤都递归
希望这有帮助:-)你能解释一下你想用这个解决什么问题吗?通常,将这样的结构展平并不会改善数据处理。以您想要的方式处理数据将是非常糟糕的。您可以在loopDict
函数中添加一个“level”/“depth”参数,并随着每次递归增加它,这就是为什么您知道何时达到第三级。
{'alpha': 'one',
'beta': {'beta1': 'two', 'beta2': 'second two'},
'gamma': {'delta': {'delta1': 'three', 'delta2': 'second three'},
'epsilon': {'epsilon1': 'five',
'epsilon2': 'second five',
'zeta.zeta1': 'four',
'zeta.zeta2': 'second four'}}}