Python 在嵌套字典中获取所有项的所有父项键
我想获得嵌套python字典中所有项的所有父键,级别不限。打个比方,如果您将嵌套字典视为包含子目录的目录,那么我想要的行为类似于glob.globdir,recursive=True 例如,假设我们有以下词典:Python 在嵌套字典中获取所有项的所有父项键,python,python-3.x,glob,Python,Python 3.x,Glob,我想获得嵌套python字典中所有项的所有父键,级别不限。打个比方,如果您将嵌套字典视为包含子目录的目录,那么我想要的行为类似于glob.globdir,recursive=True 例如,假设我们有以下词典: sample_dict = { "key_1": { "sub_key_1": 1, "sub_key_2": 2, }, "key_2": { "sub_key_1": 3, "sub_key_2": { "sub_sub_key
sample_dict = {
"key_1": {
"sub_key_1": 1,
"sub_key_2": 2,
},
"key_2": {
"sub_key_1": 3,
"sub_key_2": {
"sub_sub_key_1": 4,
},
},
}
["key_1", "sub_key_1", 1]
["key_1", "sub_key_2", 2]
["key_2", "sub_key_1", 3]
["key_2", "sub_key_2", "sub_sub_key_1", 4]
我想获得字典中每个值的完整路径:
sample_dict = {
"key_1": {
"sub_key_1": 1,
"sub_key_2": 2,
},
"key_2": {
"sub_key_1": 3,
"sub_key_2": {
"sub_sub_key_1": 4,
},
},
}
["key_1", "sub_key_1", 1]
["key_1", "sub_key_2", 2]
["key_2", "sub_key_1", 3]
["key_2", "sub_key_2", "sub_sub_key_1", 4]
只是想知道是否有一种干净的方法可以做到这一点?您可以递归地解决它
sample_dict = {
"key_1": {
"sub_key_1": 1,
"sub_key_2": 2,
},
"key_2": {
"sub_key_1": 3,
"sub_key_2": {
"sub_sub_key_1": 4,
},
}
}
def full_paths(sample_dict, paths=[], parent_keys=[]):
for key in sample_dict.keys():
if type(sample_dict[key]) is dict:
full_paths(sample_dict[key], paths=paths, parent_keys=(parent_keys + [key]))
else:
paths.append(parent_keys + [key] + [sample_dict[key]])
return paths
print(full_paths(sample_dict))
你可以递归地解决它
sample_dict = {
"key_1": {
"sub_key_1": 1,
"sub_key_2": 2,
},
"key_2": {
"sub_key_1": 3,
"sub_key_2": {
"sub_sub_key_1": 4,
},
}
}
def full_paths(sample_dict, paths=[], parent_keys=[]):
for key in sample_dict.keys():
if type(sample_dict[key]) is dict:
full_paths(sample_dict[key], paths=paths, parent_keys=(parent_keys + [key]))
else:
paths.append(parent_keys + [key] + [sample_dict[key]])
return paths
print(full_paths(sample_dict))
使用生成器通常可以简化这些类型任务的代码,使它们更具可读性,同时避免向函数传递显式状态参数。您得到的是一个生成器而不是列表,但这是一件好事,因为如果您愿意,您可以惰性地进行评估。例如:
def getpaths(d):
if not isinstance(d, dict):
yield [d]
else:
yield from ([k] + w for k, v in d.items() for w in getpaths(v))
result = list(getpaths(sample_dict))
结果将是:
[['key_1', 'sub_key_1', 1],
['key_1', 'sub_key_2', 2],
['key_2', 'sub_key_1', 3],
['key_2', 'sub_key_2', 'sub_sub_key_1', 4]]
使用生成器通常可以简化这些类型任务的代码,使它们更具可读性,同时避免向函数传递显式状态参数。您得到的是一个生成器而不是列表,但这是一件好事,因为如果您愿意,您可以惰性地进行评估。例如:
def getpaths(d):
if not isinstance(d, dict):
yield [d]
else:
yield from ([k] + w for k, v in d.items() for w in getpaths(v))
result = list(getpaths(sample_dict))
结果将是:
[['key_1', 'sub_key_1', 1],
['key_1', 'sub_key_2', 2],
['key_2', 'sub_key_1', 3],
['key_2', 'sub_key_2', 'sub_sub_key_1', 4]]
您可以使用此解决方案
sample_dict = {
"key_1": {
"sub_key_1": 1,
"sub_key_2": 2,
},
"key_2": {
"sub_key_1": 3,
"sub_key_2": {
"sub_sub_key_1": 4,
},
},
}
def key_find(sample_dict, li=[]):
for key, val in sample_dict.items():
if isinstance(val, dict):
key_find(val, li=li + [key])
else:
print(li + [key] + [val])
key_find(sample_dict)
您可以使用此解决方案
sample_dict = {
"key_1": {
"sub_key_1": 1,
"sub_key_2": 2,
},
"key_2": {
"sub_key_1": 3,
"sub_key_2": {
"sub_sub_key_1": 4,
},
},
}
def key_find(sample_dict, li=[]):
for key, val in sample_dict.items():
if isinstance(val, dict):
key_find(val, li=li + [key])
else:
print(li + [key] + [val])
key_find(sample_dict)
你试过什么?到底是什么问题?问题是我不知道怎么做。我认为@Mark Meyer解决方案是可行的。你为什么需要这样做?这似乎有点奇怪和不幸。这是一个抽象的问题,源于我工作中的一个实际问题。因为抽象,所以感觉有点奇怪。实际问题是什么?你试过什么?到底是什么问题?问题是我不知道怎么做。我认为@Mark Meyer解决方案是可行的。你为什么需要这样做?这似乎有点奇怪和不幸。这是一个抽象的问题,源于我工作中的一个实际问题。因为抽象,所以感觉有点奇怪。那么实际问题是什么呢?谢谢!这真是一个优雅的解决方案!谢谢这真是一个优雅的解决方案!谢谢你的帮助。我认为使用iInstance比Mark Meyer和Shivam Gupta建议的更好。谢谢你的帮助。我认为使用iInstance更好,正如Mark Meyer和Shivam Gupta所建议的那样。