打印python嵌套字典

时间:2016-01-17 09:10:09

标签: python dictionary nested

如果下面是我的嵌套字典,我想通过递归方式解析并打印所有值以及嵌套键的完整路径。

my_dict = {'attr':{'types':{'tag':{'name':'Tom', 'gender':'male'},'category':'employee'}}}

预期输出:

Key structure : my_dict["attr"]["types"]["tag"]["name"]<br>
value : "Tom"<br>
Key structure : my_dict["attr"]["types"]["tag"]["gender"]<br>
value : "male"<br>
Key structure : my_dict["attr"]["types"]["category"]<br>
value : "employee"<br>

我写了一个递归函数,但运行到此:

my_dict = {'attr':{'types':{'tag':{'name':'Tom','gender':'male'},'category':'employee'}}}

def dict_path(path,my_dict):
    for k,v in my_dict.iteritems():
        if isinstance(v,dict):
            path=path+"_"+k
            dict_path(path,v)
        else:
            path=path+"_"+k
            print path,"=>",v

    return
dict_path("",my_dict)

输出:

_attr_types_category =&gt;员工
_attr_types_category_tag_gender =&gt;男性
_attr_types_category_tag_gender_name =&gt;汤姆

在上面:对于男性,关键结构不应包含“类别” 如何保留正确的密钥结构?

4 个答案:

答案 0 :(得分:10)

您不应更改path函数中的dict_path()变量:

def dict_path(path,my_dict):
    for k,v in my_dict.iteritems():
        if isinstance(v,dict):
            dict_path(path+"_"+k,v)
        else:
            print path+"_"+k,"=>",v
dict_path("",my_dict)

答案 1 :(得分:4)

正如catavaran所提到的,您的问题是由于将新路径组件添加到path循环中的for变量引起的。您需要将新路径放入调用中,以便将其传递到下一级递归,并且不会干扰当前递归级别for循环中后续项的路径。

这是使用递归生成器的替代解决方案,而不是在dict_path函数内打印结果。 (FWIW,我使用print json.dumps(my_dict, indent=4)重新格式化字典。)

my_dict = {
    "attr": {
        "types": {
            "category": "employee", 
            "tag": {
                "gender": "male", 
                "name": "Tom"
            }
        }
    }
}

def dict_path(my_dict, path=None):
    if path is None:
        path = []
    for k,v in my_dict.iteritems():
        newpath = path + [k]
        if isinstance(v, dict):
            for u in dict_path(v, newpath):
                yield u
        else:
            yield newpath, v

for path, v in dict_path(my_dict):
    print '_'.join(path), "=>", v

<强>输出

attr_types_category => employee
attr_types_tag_gender => male
attr_types_tag_name => Tom

答案 2 :(得分:1)

我建议您使用python-benedict,它是具有完整键路径支持和许多实用程序方法的可靠python dict子类。

您只需要投射现有的字典:

my_dict = benedict(my_dict)

现在您的字典具有完整的密钥路径支持,您可以轻松地获取字典中所有密钥路径的列表:

print(my_dict.get_keypaths())

这里是库存储库和文档: https://github.com/fabiocaccamo/python-benedict

答案 3 :(得分:0)

只需添加上面的@catavaran代码即可。 如果dict值为list,并且list可能有dict或值本身,则此代码可能有所帮助。 我只是将分隔符修改为点。

def dict_path(path,my_dict):
    for k,v in my_dict.iteritems():
        if isinstance(v,list):
            for i, item in enumerate(v):
                dict_path( path + "." + k + "." + str(i), item)
        elif isinstance(v,dict):
            dict_path(path+"."+k,v)
        else:
            print path+"."+k, "=>", v

谢谢@catavaran,您的代码帮助了我。