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)
次。更有效的方法是将生成器链接到自定义数据结构,或手动模拟堆栈。
什么构成子字典?你如何确定哪些部分应该在子字典中,哪些部分应该被删除? – interjay 2012-03-13 09:14:50
看来,每个生成的字典必须只有一个嵌套级别的条目。换句话说,每个结果都包含字典树中每个叶子的整个路径。 – 2012-03-13 09:20:05
**投票重新开放**:在投票结束之前没有人阅读Tim Pietzcker的评论吗?我编辑的问题和标题明确无误。 – ninjagecko 2012-03-13 23:13:44