Home > Net >  Turn values of dictionnary into list
Turn values of dictionnary into list

Time:01-10

The groups_per_user function receives a dictionary, which contains group names with the list of users. Users can belong to multiple groups. Fill in the blanks to return a dictionary with the users as keys and a list of their groups as values.

This is what I did but I didn't get the expected result.

def groups_per_user(group_dictionary):
user_groups = {}
for group, users in group_dictionary.items():
    for user in users
            if user not in user_groups:
                new_user_groups = {user: group}
                user_groups.update(new_user_groups)
            else:
                user_groups[user]  = group
    return(user_groups)
print(groups_per_user({"local": ["admin", "userA"],
          "public":  ["admin", "userB"],
          "administrator": ["admin"] }))

 # it gave me this:
 {'admin': 'localpublicadministrator', 'userA': 'local', 'userB': 'public'}

 #but I want this:
 {'admin': ['local', 'public', 'administrator'], 'userA': ['local'], 'userB': ['public']}

CodePudding user response:

Change

                new_user_groups = {user: group}
                user_groups.update(new_user_groups)
            else:
                user_groups[user]  = group

to

                user_groups[user] = [group]
            else:
                user_groups[user].append( group )

CodePudding user response:

Let's look at how we can simplify this. First, we'll get a set of all usernames.

>>> d = {"local": ["admin", "userA"],
...           "public":  ["admin", "userB"],
...           "administrator": ["admin"] }
>>> set(x for lst in d.values() for x in list(lst))
{'userB', 'admin', 'userA'}
>>> users = set(x for lst in d.values() for x in list(lst))

Now, we'll use a dictionary comprehension along with d and users. And a list comprehension inside to find all of the roles associated with a given username.

>>> {name: [k for k, v in d.items() if name in list(v)] for name in users}
{'userB': ['public'], 'admin': ['local', 'public', 'administrator'], 'userA': ['local']}
>>>

CodePudding user response:

dict.setdefault or collections.defaultdict would work really well here. dict.setdefault method sets user_groups[key]=default if key is not already in user_groups (you set [] as a default value). Then in each iteration, you just append the group name to the appropriate user. So just replace

if user not in user_groups:
    new_user_groups = {user: group}
    user_groups.update(new_user_groups)
else:
    user_groups[user]  = group

with

user_groups.setdefault(user, []).append(group)

and your function will produce the desired outcome.

If you rather use collections.defaultdict, you can modify your function minimally as below. Similar to dict.setdefault, collections.defaultdict provides a default value for the key that doesn't exist. You can initialize an empty list as default value by passing list constructor to collections.defaultdict.

from collections import defaultdict
def groups_per_user(group_dictionary):
    user_groups = defaultdict(list)
    for group, users in group_dictionary.items():
        for user in users:
            user_groups[user].append(group)
    return(user_groups)

Output:

{'admin': ['local', 'public', 'administrator'], 'userA': ['local'], 'userB': ['public']}
  •  Tags:  
  • Related