views:

269

answers:

3

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())
+4  A: 

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())
Nadia Alramli
I changed that to make it a class member of Team but it throws a 'Too many values to unpack' exception when implemented like so:return sum(value.get(category, 0) for key, value in self.lineup)
Wells
Please try again now. I fixed it.
Nadia Alramli
Works as well! Thank you.
Wells
Sorry for being pedantic, I think you mean you're using a generator expression, not a list comprehension.
Jeffrey Harris
@Jeffrey, I fixed it. Thanks
Nadia Alramli
+1  A: 
def total(category):
    return sum([ghl[man][category] for man in game.home.lineup.keys()])
inspectorG4dget
return sum(man[category] for man in self.lineup.keys())TypeError: string indices must be integers, not str
Wells
Sorry about the bad code. It has been changed now and tested against your test case. It works. The problem was with misplaced '[]'s, which was a typo. It's test time before the finals, which is why the quality of my code isn't at it's best. Sorry again
inspectorG4dget
A: 
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.

Stigma
Weird code. Wouldn't `team in self.lineup` be a constant over the entire function? If so, it's the same as this: `return sum(self.lineup[aKey][team] for aKey in self.lineup) if team in self.lineup else 0` or even `return sum(something[team] for something in self.lineup.values()) if team in self.lineup else 0`
hughdbrown
Yeah, I made a booboo in my rush, which is fixed now (thanks!). `if team in self.lineup[aKey]:` is the proper line. Either way, other people had already posted the proper answers by the time I posted, so my focus was primarily on having something to use with the second block of code which had not been addressed yet.
Stigma