我正在尝试计算具有相同子键的子字典的tot值。我有一个包含相关键mylist
的列表,我只需要计算列表中每个元素的值总数。
mylist = ['age','answ1', 'answ2', 'answ3']
d = {'01': {'age':19, 'answ1':3, 'answ2':7, 'answ3':2}, '02': {'age':52, 'answ1':8, 'answ2':1, 'answ3':10},...}
我尝试过
tot = []
for k,v in d.items():
for ke, va in v.items():
for i in mylist[0:]
count=0
if ke == i:
count+=v[ke]
tot.append(count)
但不是按相同键值的总和,而是按字典中出现的顺序获取不同键的值。 预期结果将是
tot = [71, 11, 8, 12]
我得到的是
tot = [19, 3, 7, 2, 52, 8, 1, 10]
答案 0 :(得分:4)
使用collections.Counter
:
>>> ctr = sum(map(Counter, d.values()), Counter())
>>> [ctr[x] for x in mylist]
[71, 11, 8, 12]
或者:
>>> [sum(e[k] for e in d.values()) for k in mylist]
[71, 11, 8, 12]
万一某些子命令可能缺少键,只需使用e.get(k, 0)
。 Counter
解决方案不需要它,默认情况下会提供零。
嗯,因为您现在接受了dict
结果解决方案...
>>> dict(sum(map(Counter, d.values()), Counter()))
{'age': 71, 'answ1': 11, 'answ2': 8, 'answ3': 12}
也许只是
>>> sum(map(Counter, d.values()), Counter())
Counter({'age': 71, 'answ3': 12, 'answ1': 11, 'answ2': 8})
尽管这些键可能具有比所需键更多的键,但是如果您的数据中有更多键。
答案 1 :(得分:1)
如果您希望将结果存储在字典中,则可以使用列表中的键创建一个并在其中计算结果。
result = {i: 0 for i in mylist}
for k, v in d.items():
result['age'] += v['age']
result['answ1'] += v['answ1']
result['answ2'] += v['answ2']
result['answ3'] += v['answ3']
result
{'age': 71, 'answ1': 11, 'answ2': 8, 'answ3': 12}
但这确实取决于键的不变,顺序无关紧要。
编辑
使用以下更新,可以与密钥名称无关地执行此操作。请注意,它会增加一次迭代。
result = {i: 0 for i in mylist}
for k, v in d.items():
for ke, va in v.items():
result[ke] += v[ke]
答案 2 :(得分:0)
mylist = ['age','answ1', 'answ2', 'answ3']
d = {'01': {'age':19, 'answ1':3, 'answ2':7, 'answ3':2}, '02': {'age':52, 'answ1':8, 'answ2':1, 'answ3':10}}
tot = [0] * len(mylist)
for k in d:
for idx, i in enumerate(mylist):
tot[idx] += d[k].get(i, 0)
print(tot)
打印:
[71, 11, 8, 12]
答案 3 :(得分:0)
尝试以下代码
for i in mylist:
count=0
for k,v in d.items():
for ke, va in v.items():
if ke == i:
count+=va
tot.append(count)
〜
答案 4 :(得分:0)
您可以使用列表推导zip
和map
完成此操作。首先,我们要从每个子字典中提取相应的值:
>>> vals = [[v[k] for k in mylist] for v in d.values()]
>>> vals
[[19, 3, 7, 2], [52, 8, 1, 10]]
现在,我们希望对所有子列表执行按元素求和:
>>> result = map(sum, zip(*vals))
>>> list(result)
[71, 11, 8, 12]
将它们全部放在一行中:
>>> result = map(sum, zip(*([v[k] for k in mylist] for v in d.values())))
>>> list(result)
[71, 11, 8, 12]
这种方法的好处是仅访问我们要构建的密钥,而不是构建完整的Counter
,然后再提取数据。
答案 5 :(得分:0)
相同但不同。
>>> import operator
>>> f = operator.itemgetter(*mylist)
>>> vals = map(f,d.values())
>>> sums = map(sum,zip(*vals))
>>> result = dict(zip(mylist,sums))
>>> result
{'age': 71, 'answ1': 11, 'answ2': 8, 'answ3': 12}
如果您不想要该字典,则跳过该字典并使用result = list(sums)