Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何展平字典';它只比3级深_Python_Json_Nested_Flatten - Fatal编程技术网

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'}}}