Python 嵌套字典:提取树叶的路径

Python 嵌套字典:提取树叶的路径,python,Python,我有一个Python嵌套字典,如下所示: {'dist_river': {'high': {'wind_speed': {'1': {'population': {'high': {'school': {'high':'T', 'medium':'T', 'low':'F'} }, 'medium':

我有一个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
谢谢你的帮助


社区编辑:似乎每个生成的字典对于每个嵌套级别只能有一个条目。换句话说,每个结果都包含字典树中每个叶子的完整路径Tim Pietzcker 13小时前,这与从字典中“获取”任何其他值的方式完全相同

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
也许是这样:

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
演示:


旁注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')]
(很容易从“直截了当”的答案中提取,这恰好是thg435的答案。)


旁注2:请注意,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被重新产生
深度(L)
次。更有效的方法是使用自定义数据结构链接生成器,或者手动模拟堆栈。

这要复杂得多。你需要一个递归的方法来“走下”字典树。也许我误解了这个问题。什么是子字典?如何确定哪些部分应该在子词典中,哪些部分应该删除?似乎每个生成的词典对于每个嵌套级别只能有一个条目。换句话说,每个结果都包含字典树中每个叶子的完整路径。投票重新打开:投票关闭之前没有人读过Tim Pietzcker的评论吗?我已经将问题和标题编辑得非常清楚。非常好。我希望我能不止一次地对此进行投票。非常感谢你们,你们的答案非常有帮助。你们的答案很好,我不明白为什么这么多人在不理解问题的时候才选择结束这个问题,stackoverflow最近正在减少。
...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')]
>>> 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'}}]