Reputation: 700
Given a dictionary and a string as parameters, return a new dictionary containing the item specified as the category(second parameter, one of 'city', 'sport', 'name') as a key and it's associated value. If there are more than one occurrence of the item than take the sum of the values.
Ex.
>>> get_wins_by_category(d, 'city')
{'Toronto': 34, 'Ottawa': 45}
>>> get_wins_by_category(d, 'sport')
{'basketball': 31, 'hockey': 48}
>>> get_wins_by_category(d, 'name')
{'Raptors': 10, 'Blues': 21, 'Senators': 45, 'Leafs': 3}
What I got so far:
d = {('Raptors', 'Toronto', 'basketball'): 10,
('Blues', 'Toronto', 'basketball'): 21,
('Senators', 'Ottawa', 'hockey'): 45,
('Leafs', 'Toronto', 'hockey'): 3}
def get_wins_by_category(dct, category):
new_dict = {}
if category == 'city':
for key in dct.keys():
new_dict[key[1]] = #todo
elif category == 'sport':
for key in dct.keys():
new_dict[key[2]] = #todo
elif category == 'name':
for key in dct.keys():
new_dict[key[0]] = #todo
return new_dict
The problem I have is what to write after the equal sign. I know that if there are more than one occurrence of the item that take the sum of all the values containing that item but I don't know how to write it as code. Also a note that the 3-tuple will always be in that order: name, city, sport.
Upvotes: 3
Views: 729
Reputation: 122061
The following removes the need for the if:
blocks by defining the inputs in cats
d = {('Raptors', 'Toronto', 'basketball'): 10,
('Blues', 'Toronto', 'basketball'): 21,
('Senators', 'Ottawa', 'hockey'): 45,
('Leafs', 'Toronto', 'hockey'): 3}
cats = ("team", "city", "sport")
def get_wins_by_category(d, cats, cat):
if cat in cats:
return {t: sum(v for k, v in d.items() if t in k)
for t in set(key[cats.index(cat)] for key in d)}
Upvotes: 0
Reputation: 250981
Use collections.defaultdict
, no if-else required:
from collections import defaultdict
def get_wins_by_category(team_to_win, category):
d = {'name':0, 'city':1, 'sport':2}
dic = defaultdict(int)
for k, v in team_to_win.items():
dic[k[d[category]]] += v
return dic
...
>>> get_wins_by_category(d, 'city')
defaultdict(<type 'int'>, {'Toronto': 34, 'Ottawa': 45})
>>> get_wins_by_category(d, 'sport')
defaultdict(<type 'int'>, {'basketball': 31, 'hockey': 48})
>>> get_wins_by_category(d, 'name')
defaultdict(<type 'int'>, {'Senators': 45, 'Blues': 21, 'Raptors': 10, 'Leafs': 3})
Another alternative is collections.Counter
:
from collections import Counter
def get_wins_by_category(team_to_win, category):
#index each category points to
d = {'name':0, 'city':1, 'sport':2}
dic = Counter()
for k, v in team_to_win.items():
dic[k[d[category]]] += v
return dic
...
>>> get_wins_by_category(d, 'city')
Counter({'Ottawa': 45, 'Toronto': 34})
>>> get_wins_by_category(d, 'sport')
Counter({'hockey': 48, 'basketball': 31})
>>> get_wins_by_category(d, 'name')
Counter({'Senators': 45, 'Blues': 21, 'Raptors': 10, 'Leafs': 3})
Upvotes: 2
Reputation: 365767
Using the wrong data structure always makes your code more complicated to write, and to read, and often to run efficiently as well.
If you want to look something up by value, use a dict (or a namedtuple) with that value as a key, don't loop over the whole list and search one by one. If you need to create multiple dicts, do so.
For example:
from collections import Counter
teams, cities, sports = Counter(), Counter(), Counter()
for keys, score in d.items():
team, city, sport = keys
teams[team] += score
cities[city] += score
sports[sport] += score
categories = {'team': teams, 'city': cities, 'sport': sports}
Now your code is trivial:
def get_wins_by_category(category):
return categories[category]
Or, alternatively, keep all the scores for each one, so you can do other things besides sum the scores (e.g., average them):
from collections import Counter
teams, cities, sports = defaultdict(list), defaultdict(list), defaultdict(list)
for keys, score in d.items():
team, city, sport = keys
teams[team].append(score)
cities[city].append(score)
sports[sport].append(score)
categories = {'team': teams, 'city': cities, 'sport': sports}
def get_wins_by_category(category):
return {key: sum(scores) for key, scores in categories[category].items()}
def get_avg_wins_by_category(category):
return {key: sum(scores)/len(scores)
for key, scores in categories[category].items()}
Upvotes: 1
Reputation: 4362
if category == 'city':
for key, value in dct.items():
new_dict[key[1]] += value
You get the point..
Upvotes: 0