Reputation: 480
So I'm trying to group the following object:
staffs={
"James":["basket_ball","swimming"],
"Cook":"swimming",
"Peter":"basket_ball",
"Ben":"coding",
"Joe":"coding"
}
Where the expected output should be:
{
"basket_ball": ["James","Peter"],
"swimming":["Cook","James"],
"coding":["Ben", "Joe"]
}
Following is what I have done:
def group_by_hobby(staffs):
hobbies = staffs.values()
obj = {}
for h in hobbies:
if(isinstance(h, list)):
for i in h:
obj[i] = [k for k in staffs.keys() if staffs[k] == h]
else:
obj[h] = [k for k in staffs.keys() if staffs[k] == h]
print(obj)
But the key with the value of list is not being considered. I even added a check if its a list, loop through it and separate the values but doesn't seem to be working. Any idea what I might be missing here?
Apologies for the explanation, still new to Python.
Upvotes: 1
Views: 431
Reputation: 21
The problem with your code is, you are again assigning new list to the key even if value for the key was already existing, use this modification to append in list instead of assigning new values
You can use this:
def group_by_hobby(staffs):
hobbies = staffs.values()
print hobbies
obj = {}
for h in hobbies:
if(isinstance(h, list)):
for i in h:
if i not in obj:
obj[i] = []
obj[i] = obj[i]+[k for k in staffs.keys() if staffs[k] == h]
else:
if h not in obj:
obj[h] = []
obj[h] = obj[h]+[k for k in staffs.keys() if staffs[k] == h]
print obj
Upvotes: 0
Reputation: 707
That's another way to do your job:
staffs={
"James":["basket_ball","swimming"],
"Cook":"swimming",
"Peter":"basket_ball",
"Ben":"coding",
"Joe":"coding"
}
hobbies = dict()
for x in staffs.values():
for y in x if isinstance(x, list) else [x]:
hobbies[y] = []
for x in staffs.keys():
for y in staffs[x] if isinstance(staffs[x], list) else [staffs[x]]:
hobbies[y].append(x)
print(hobbies)
Upvotes: -1
Reputation: 107095
For each item in the staffs
dict, you can iterate through hobbies if the value of the dict item is a list, or make it a list by creating a one-item list with it. Use the dict.setdefault
method to initialize each non-existing dict key with a new list:
output = {}
for name, hobbies in staffs.items():
for hobby in hobbies if isinstance(hobbies, list) else [hobbies]:
output.setdefault(hobby, []).append(name)
output
becomes:
{'basket_ball': ['James', 'Peter'], 'swimming': ['James', 'Cook'], 'coding': ['Ben', 'Joe']}
Upvotes: 3
Reputation: 23002
First, you need a function to get the list of hobbies:
def get_hobbies(str_or_list):
return [str_or_list] if isinstance(str_or_list, str) else str_or_list
Then you can use collections.defaultdict to create a dictionary of lists:
result = collections.defaultdict(list)
for name, staff_hobbies in staffs.items():
for hobby in get_hobbies(staff_hobbies):
result[hobby].append(name)
You get what you want:
defaultdict(<class 'list'>, {'basket_ball': ['James', 'Peter'], 'swimming': ['James', 'Cook'], 'coding': ['Ben', 'Joe']})
Upvotes: 0
Reputation: 672
If you know what hobbies will be present you can simply do:
staffs={
"James":["basket_ball","swimming"],
"Cook":["swimming"],
"Peter":["basket_ball"],
"Ben":["coding"],
"Joe":["coding"]
}
hobbies={
"basket_ball":[],
"swimming":[],
"coding":[]
}
for key,value in staffs.items():
for hobby in value:
hobbies[hobby].append(key)
print(hobbies)
Upvotes: 0
Reputation: 9518
You need to be appending to the arrays rather than replacing them in your resulting obj:
def group_by_hobby(staffs):
obj = {}
for person in staffs.keys():
hobbies = staffs[person]
print('hobbies: {}'.format(hobbies))
if(isinstance(hobbies, list)):
for hobby in hobbies:
if hobby not in obj.keys():
obj[hobby] = []
print(hobby)
obj[hobby].append(person)
else:
if hobbies not in obj.keys():
obj[hobbies] = []
obj[hobbies].append(person)
print(obj)
Upvotes: 2