问题
I have a nested dictionary
dict_features = {'agitacia/6.txt': {'samoprezentacia': 0, 'oskorblenie': 1},
'agitacia/21.txt': {'samoprezentacia': 0, 'oskorblenie': 0}}
I'm trying to output a new dictionary features_agit_sum
which consists of a key from a previous dictionary and a sum of values of a "deeper" dictionary. So I need to sum 0+1 that is int type. The output should be:
{'agitacia/6.txt': 1, 'agitacia/21.txt': 0}
Below are several attempts with different errors; don't how to iterate correctly:
features_agit_sum = {}
def vector_agit_sum(dict_features):
for key, value in dict_features:
features_agit_sum[key] = sum(dict_features.items()[key])
print (features_agit_sum)
return features_agit_sum
ValueError: too many values to unpack (expected 2) dict_features.items()[key] - try to access deeper dict
features_agit_sum = {}
def vector_agit_sum(dict_features):
for key in dict_features:
for item, value in dict_features.items():
features_agit_sum[key] = sum([item])
print (features_agit_sum)
return features_agit_sum
TypeError: unsupported operand type(s) for +: 'int' and 'str' - Why, it's integers!
features_agit_sum = {}
def vector_agit_sum(dict_features):
files = dict_features.keys()
for key, value in dict_features.items():
features_agit_sum[files] = sum(dict_features.items()[key])
print (features_agit_sum)
return features_agit_sum
TypeError: 'dict_items' object is not subscriptable
回答1:
Use a dict comprehension:
{key: sum(value.itervalues()) for key, value in dict_features.iteritems()}
If you are using Python 3, remove the iter
prefixes, so use .values()
and .items()
.
Demo:
>>> dict_features = {'agitacia/6.txt': {'samoprezentacia': 0, 'oskorblenie': 1}, 'agitacia/21.txt': {'samoprezentacia': 0, 'oskorblenie': 0}}
>>> {key: sum(value.itervalues()) for key, value in dict_features.iteritems()}
{'agitacia/21.txt': 0, 'agitacia/6.txt': 1}
回答2:
Try this, using a dictionary comprehension (this will work in both Python 2.7+ and 3.x):
{ k : sum(v.values()) for k, v in dict_features.items() }
If using Python 2.7+, the recommended way is to explicitly use iterators, in Python 3.x the previous snippet already uses them:
{ k : sum(v.itervalues()) for k, v in dict_features.iteritems() }
Either way, it returns the expected result:
{'agitacia/21.txt': 0, 'agitacia/6.txt': 1}
回答3:
Use isinstance
to check the type and take the correct action. If it is a int
, add it to the running total. Otherwise, recurse to get the total sum contained within that dictionary.
dict_features = {'agitacia/6.txt': {'samoprezentacia': 0, 'oskorblenie': 1}, 'agitacia/21.txt': {'samoprezentacia': 0, 'oskorblenie': 0}}
def countDict(d):
total = 0
for i in d.itervalues():
if isinstance(i,int):
total += i
else:
total += countDict(i)
return total
result = {}
for k,v in dict_features.iteritems():
result[k] = countDict(v)
print result
回答4:
the shortest (and fastest) way may be as this:
features_agit_sum = dict([(k, sum(dict_features[k].values())) for k, v in dict_features.iteritems()])
来源:https://stackoverflow.com/questions/18033655/taking-sums-of-nested-values-of-nested-dictionary