Wells
Wells

Reputation: 10979

A dictionary with values that are dictionaries: trying to sum across those keys in python

Data structure is a dictionary, each value is another dictionary, like:

>>> from lib import schedule
>>> schedule = schedule.Schedule()
>>> game = schedule.games[0]
>>> game.home
<lib.schedule.Team instance at 0x9d97c6c>
>>> game.home.lineup
{'guerv001': {'HR': 392, '1B': 1297}, 'kendh001': {'HR': 12, '1B': 201}, 'andeg001': {'HR': 272, '1B': 1572}, 'mattg002': {'HR': 104, '1B': 632}, 'figgc001': {'HR': 26, '1B': 672}, 'iztum001': {'HR': 16, '1B': 253}, 'huntt001': {'HR': 213, '1B': 834}, 'quinr002': {'HR': 23, '1B': 200}, 'napom001': {'HR': 46, '1B': 96}}

Would like Team to have a method getTotals(self, category) where if you called:

game.home.getTotals('HR')

The method would, in this case, yield:

1104

Essentially you can see what I'm trying to do. Any ideas?

update: I have this working with two list comprehensions but would like to winnow it down to one:

def getTotals(self, category):
    cats = [x for x in self.lineup.values()]
    return sum([x[category] for x in cats])

another update: Based on inspectorg4dget's helpful feedback below I've gotten it. Thanks!

def getTotals(self, category):
    return sum(self.lineup[man][category] for man in self.lineup.keys())

final update: Based on Nadia's feedback, here's another approach:

def getTotals(self, category):
    return sum(value.get(category, 0) for value in self.lineup.values())

Upvotes: 1

Views: 536

Answers (3)

Nadia Alramli
Nadia Alramli

Reputation: 115011

You can use a generator expression:

def total(category):
    return sum(value.get(category, 0) for value in game.home.lineup.values())

>>> total('HR')
1104

I used dict.get to make the default 0 if the category is missing from any dictionary.

The self version:

def total(self, category):
    return sum(value.get(category, 0) for value in self.lineup.values())

Upvotes: 4

Stigma
Stigma

Reputation: 1736

def myGetTotals(self, team):
    count = 0
    for aKey in self.lineup:
        if team in self.lineup[aKey]:
            count = count + self.lineup[aKey][team]
    return count

Kind of verbose, but meh. Do pay attention to the first parameter which is the instance. Now, if you want it to be part of all team objects, you'd need to modify the class:

lib.schedule.Team.getTotals = myGetTotals

That should add said object to the class definition and make existing objects capable of using it from there on forth. It's been a few months since I coded some Python, but it should work.

Upvotes: 0

inspectorG4dget
inspectorG4dget

Reputation: 114035

def total(category):
    return sum([ghl[man][category] for man in game.home.lineup.keys()])

Upvotes: 1

Related Questions