Ali
Ali

Reputation: 480

Group by value of keys where values can be a list

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

Answers (6)

Kishan Nigam
Kishan Nigam

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

Giannis Clipper
Giannis Clipper

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

blhsing
blhsing

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

Laurent LAPORTE
Laurent LAPORTE

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

Samuel Middendorp
Samuel Middendorp

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

wogsland
wogsland

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

Related Questions