Trying to find sums of unique values within a nested dictionary. (See example!)

Viewed 292

Let's say I have this variable list_1 which is a list of dictionaries. Each dictionary has a nested dictionary called "group" in which it has some information including "name".

What I'm trying to do is to sum the scores of each unique group name.

So I am looking for an output similar to:

Total Scores in (Ceramics) = (18)
Total Scores in (Math) = (20)
Total Scores in (History) = (5)

I have the above info in parenthesis because I would like this code to work regardless of the amount of items in the list, or amount of unique groups represented.

The list_1 variable:

    list_1 = [

    {"title" : "Painting",
     "score" : 8,
     "group" : {"name" : "Ceramics",
                "id" : 391}
     },

    {"title" : "Exam 1",
     "score" : 10,
     "group" : {"name" : "Math",
                "id" : 554}
     },

    {"title" : "Clay Model",
     "score" : 10,
     "group" : {"name" : "Ceramics",
                "id" : 391}
     },

    {"title" : "Homework 3",
     "score" : 10,
     "group" : {"name" : "Math",
                "id" : 554}
     },

    {"title" : "Report 1",
     "score" : 5,
     "group" : {"name" : "History",
                "id" : 209}
     },

    ]

My first idea was to create a new list variable and append each unique group name. Here's the code for that. But will this help in ultimately finding the sum of the scores for each one of these?

group_names_list = []
for item in list_1:
    group_name = item["group"]["name"]
    if group_name not in group_names_list:
        group_names_list.append(group_name)

This gives me the value of group_names_list as:

['Ceramics','Math','History']

Any help or suggestions are appreciated! Thanks.

3 Answers

You can use a dict to keep track of scores per name:

score_dict = dict()
for d in list_1:
    name = d['group']['name']
    if name in score_dict:
        score_dict[name] += d['score']
    else:
        score_dict[name] = d['score']

print(score_dict)

RESULTS: {'Ceramics': 18, 'Math': 20, 'History': 5}

data = {}
for item in list_1: # for each item in our list
   # set our category to its existing value (or 0) + the new score
   data[item['group']['name']] = item['score'] + data.get(item['group']['name'],0)

print(data) # output = {'History': 5, 'Math': 20, 'Ceramics': 18}

then you can print it easy enough using format strings

for group_name,scores_summed in data.items():
    print("Totals for {group_name} = {scores_summed}".format(group_name=group_name,scores_summed=scores_summed))

Both the answers of @JacobIRR and @JoranBeasley are great, as alternative you could do the following:

data = [
    {"title": "Painting", "score": 8, "group": {"name": "Ceramics", "id": 391}},
    {"title": "Exam 1", "score": 10, "group": {"name": "Math", "id": 554}},
    {"title": "Clay Model", "score": 10, "group": {"name": "Ceramics", "id": 391}},
    {"title": "Homework 3", "score": 10, "group": {"name": "Math", "id": 554}},
    {"title": "Report 1", "score": 5, "group": {"name": "History", "id": 209}}
]

result = {}
scores = iter((e['group']['name'], e['score']) for e in data)
for name, score in scores:
    result[name] = result.get(name, 0) + score

print(result)

Output

{'Ceramics': 18, 'History': 5, 'Math': 20}
Related