2012-03-13 99 views
3

我有一个Python嵌套字典如下所示:嵌套的字典:解压路径叶

{'dist_river': 
    {'high': 
    {'wind_speed': 
     {'1': 
     {'population': 
      {'high': 
      {'school': 
       {'high':'T', 'medium':'T', 'low':'F'} 
      }, 
      'medium': 
       {'land_cover': 
       {'Mix_garden': 
        {'income_source': 
        {'Plantation':'T', 'Agriculture':'F'} 
        } 
       } 
       } 
      } 
      } 
     } 
     }, 
    'low': 'F' 
    } 
} 

我怎样才能从分字典嵌套词典?例如,来自DIC分字典:

results = [ 
    {'dist_river': 
    {'high': 
     {'wind_speed': 
     {'1': 
     {'population': 
     {'high': 
      {'school': 
      {'high': 'T', 'medium': 'T', 'low': 'F'} 
      }}}}}}}, 

    {'dist_river': 
    {'high': 
     {'wind_speed': 
     {'1': 
     {'population': 
     {'medium': 
      {'land_cover': 
      {'Mix_garden': 
      {'income_source': 
      {'Plantation': 'T', 'Agriculture': 'F'} 
      }}}}}}}}}, 

    {'dist_river': 
    {'low': 'F'} 
    } 
] 

lengths(results) == 3 

谢谢您的帮助

社区编辑:看来,每个结果字典只能有一个嵌套的每级条目。换句话说,每个结果都包含字典树中每个叶子的整个路径。 - 蒂姆Pietzcker 13小时前

+1

什么构成子字典?你如何确定哪些部分应该在子字典中,哪些部分应该被删除? – interjay 2012-03-13 09:14:50

+1

看来,每个生成的字典必须只有一个嵌套级别的条目。换句话说,每个结果都包含字典树中每个叶子的整个路径。 – 2012-03-13 09:20:05

+1

**投票重新开放**:在投票结束之前没有人阅读Tim Pietzcker的评论吗?我编辑的问题和标题明确无误。 – ninjagecko 2012-03-13 23:13:44

回答

0

它的完成方式与从字典中“获取”任何其他完全相同。

print dic1['dist_river']['high'] 

等等。

编辑:

在情况下,我误解了这个问题,它的的确确是越来越一次所有类型的字典列表,这里的情况下,有一个在他们每个人只需一个键为例:

def get_nested_dicts(d): 
    dicts = [] 
    probe = d 
    while type(probe) == dict: 
     dicts.append(probe) 
     probe = probe.values()[0] 
    return dicts 
+0

这比这复杂得多。你需要一个递归的方法来“散步”字典树。 – 2012-03-13 09:13:09

+0

也许我误解了这个问题。 – 2012-03-13 09:19:23

1

也许这:

def enum_paths(p): 
    if not hasattr(p, 'items'): 
     yield p 
    else: 
     for k, v in p.items(): 
      for x in enum_paths(v): 
       yield {k: x} 


for x in enum_paths(dic): 
    print x 
4
import collections 

def isDict(d): 
    return isinstance(d, collections.Mapping) 

def isAtomOrFlat(d): 
    return not isDict(d) or not any(isDict(v) for v in d.values()) 

def leafPaths(nestedDicts, noDeeper=isAtomOrFlat): 
    """ 
     For each leaf in NESTEDDICTS, this yields a 
     dictionary consisting of only the entries between the root 
     and the leaf. 
    """ 
    for key,value in nestedDicts.items(): 
     if noDeeper(value): 
      yield {key: value} 
     else: 
      for subpath in leafPaths(value): 
       yield {key: subpath} 

演示:

>>> pprint.pprint(list(leafPaths(dic))) 
[{'dist_river': {'high': {'wind_speed': {'1': {'population': {'high': {'school': {'high': 'T', 
                        'low': 'F', 
                        'medium': 'T'}}}}}}}}, 
{'dist_river': {'high': {'wind_speed': {'1': {'population': {'medium': {'land_cover': {'Mix_garden': {'income_source': {'Agriculture': 'F', 
                                 'Plantation': 'T'}}}}}}}}}}, 
{'dist_river': {'low': 'F'}}] 

旁注1:但是,除非这个格式是必要由于某种原因,我个人觉得它会更好,以产生节点元组的方式,例如是这样的:

...noDeeper=lambda x:not isDict(x)... 
...yield tuple(value) 
...yield (key,)+subpath 

[('dist_river', 'high', 'wind_speed', '1', 'population', 'high', 'school', 'high', 'T'), 
('dist_river', 'high', 'wind_speed', '1', 'population', 'high', 'school', 'medium', 'T'), 
('dist_river', 'high', 'wind_speed', '1', 'population', 'high', 'school', 'low', 'F'), 
('dist_river', 'high', 'wind_speed', '1', 'population', 'medium', 'land_cover', 'Mix_garden', 'income_source', 'Plantation', 'T'), 
('dist_river', 'high', 'wind_speed', '1', 'population', 'medium', 'land_cover', 'Mix_garden', 'income_source', 'Agriculture', 'F'), 
('dist_river', 'low', 'F')] 


阿里纳斯2(从“简单”的答案,这恰好是thg435的答案很容易提取。):请注意,幼稚的做法也不是什么OP正在寻找。天真的实施将有noDeeper=lambda x:not isDict(x),与结果:

>>> pprint.pprint(list(leafPaths(dic))) 
[{'dist_river': {'high': {'wind_speed': {'1': {'population': {'high': {'school': {'high': 'T'}}}}}}}}, 
{'dist_river': {'high': {'wind_speed': {'1': {'population': {'high': {'school': {'medium': 'T'}}}}}}}}, 
{'dist_river': {'high': {'wind_speed': {'1': {'population': {'high': {'school': {'low': 'F'}}}}}}}}, 
{'dist_river': {'high': {'wind_speed': {'1': {'population': {'medium': {'land_cover': {'Mix_garden': {'income_source': {'Plantation': 'T'}}}}}}}}}}, 
{'dist_river': {'high': {'wind_speed': {'1': {'population': {'medium': {'land_cover': {'Mix_garden': {'income_source': {'Agriculture': 'F'}}}}}}}}}}, 
{'dist_river': {'low': 'F'}}] 

编辑:这是一个低效率的算法。每片叶片L重新产生depth(L)次。更有效的方法是将生成器链接到自定义数据结构,或手动模拟堆栈。

+0

非常好。我希望我可以不止一次地赞扬这一点。 – 2012-03-13 09:54:02

+0

非常感谢,您的回答非常有帮助 – Imas 2012-03-14 02:33:53

+0

您的回答非常好,我不明白为什么这么多人选择只在他们不明白问题时才会关闭问题,最近stackoverflow正在运行。 – 2017-12-12 09:07:00