我正在尝试定义一个函数,它允许我在dict的各个级别获取值计数。例如,如果我有类似的东西:
vehicles = {
'Ford': {
'Falcon': {
'2008': 10,
'2009': 12,
'2010': 5
}
},
'Holden': {
'Commodore': {
'2008': 15,
'2009': 11,
'2010': 5
}
}
}
我希望能够调用一个能够计算每个深度值的函数。因此,在深度0处,函数将返回每个值的总和(58)。在深度1处,函数将返回带有{'Ford': 27, 'Holden': 31}
的字典。在深度2处,函数将返回带有{'Ford': {'Falcon': 27}, 'Holden': {'Commodore': 31}}
的字典。等...
我认为我需要挖掘到最大深度并开始对值进行求值,因为我向后移动了水平,但我对Python很新,我正在努力。可能我需要使用递归?
感谢您的帮助。
答案 0 :(得分:2)
我的解决方案,未经过全面测试
def sum_values(data):
if type(data.values()[0]) != dict:
return sum(data.values())
else:
return sum(sum_values(v) for v in data.values())
def depth_values(data, depth = 0):
if depth == 0:
return sum_values(data)
else:
return dict(
(k, depth_values(v, depth-1))
for k, v in data.items()
)
TEST:
print depth_values(vehicles, 0) # >> 58
print depth_values(vehicles, 1) # >> {'Holden': 31, 'Ford': 27}
print depth_values(vehicles, 2) # >> {'Holden': {'Commodore': 31}, 'Ford': {'Falcon': 27}}
print depth_values(vehicles, 3) # exceptions
答案 1 :(得分:1)
这似乎可以解决这个问题,虽然我做了一些欺骗并进行了类型检查(这就像你可以得到的那样是非语音的),而且我假设词典中只有整数和键。我会注意到这种方法适用于不均匀分布的树。
def score(n):
if type(n) == int:
return n
else:
return sum([score(n[x]) for x in n])
def fold_dict(xs, d):
if d == 1:
if type(xs) == int:
return xs
return {n: score(xs[n]) for n in xs}
else:
if type(xs) == int:
return xs
return {n: fold_dict(xs[n], d - 1) for n in xs}
示例输入,输出:
>>> y = {'a': {'a1': {'a11': 5, 'a12': 2, 'a13': 8}, 'a2': 6}, 'b': 7, 'c': {'c1': 18, 'c2': 1}}
>>> fold_dict(y, 1)
{'a': 21, 'c': 19, 'b': 7}
>>> fold_dict(y, 2)
{'a': {'a1': 15, 'a2': 6}, 'c': {'c2': 1, 'c1': 18}, 'b': 7}
答案 2 :(得分:0)
您可以使用isinstance
和recursion
例如,
depth = 0
dict = { ... }
def find_depth(dict):
# dict = { ... }
for key in dict:
if isinstance(dict[key], dict):
depth += 1
find_depth(dict[key])
break
答案 3 :(得分:0)
def values_at_depth(d, depth):
if depth == 0:
sum = 0
for k, v in d.iteritems():
if hasattr(v, "keys"):
sum += values_at_depth(v, 0)
else:
sum += v
return sum
else:
ret = {}
for k, v in d.iteritems():
ret[k] = values_at_depth(v, depth-1)
return ret
答案 4 :(得分:0)
如果有人感兴趣,我修改了@Ned Batchelder的函数来返回一个元组,除了报告值的总和之外,还报告不同深度的键数。希望这是有道理的......
无论如何,这是:
def values_at_depth(d, depth = 0):
if depth == 0:
sumVal = 0
sumKey = 0
for k, v in d.iteritems():
if hasattr(v, "keys"):
sumKey += collectCnt(v, 0)[0]
sumVal += collectCnt(v, 0)[1]
else:
sumVal += v
sumKey += 1
return (sumKey,sumVal)
else:
ret = {}
for k, v in d.iteritems():
ret[k] = collectCnt(v, depth-1)
return ret
PS。我不知道在哪里提供这些额外的信息。如果它应该在其他地方,请告诉我。