【问题标题】:Print complete key path for all the values of a python nested dictionary打印python嵌套字典的所有值的完整键路径
【发布时间】:2016-04-22 13:32:51
【问题描述】:

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

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 => 员工
_attr_types_category_tag_gender => 男性
_attr_types_category_tag_gender_name => 汤姆

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

【问题讨论】:

  • 这不是代码编写或教程服务;你知道你想要一个递归函数,那么为什么不试着写一个呢?
  • 编辑问题 使用minimal reproducible example
  • 你离得太近了! FWIW,当你第一次学习编写递归函数时,这是一个相当常见的错误,所以希望你下次记得。 :)

标签: python dictionary nested


【解决方案1】:

只需添加到上面的@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,您的代码帮助了我。

【讨论】:

    【解决方案2】:

    正如 catavaran 提到的,您的问题是由将新路径组件添加到 for 循环内的 path 变量引起的。您需要将新路径放入调用中,以便将其传递到下一个递归级别,并且不会在当前递归级别干扰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
    

    【讨论】:

    【解决方案3】:

    您不应更改 dict_path() 函数中的 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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-16
      • 2019-10-05
      • 2021-06-11
      • 2015-09-11
      • 1970-01-01
      • 2016-01-21
      相关资源
      最近更新 更多