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']}
