1

The groups_per_user function receives a dictionary, which contains group names with the list of users. Like the groups in Linux system. 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.

basically I'm trying to reverse the assignment of groups to users instead of users to groups

That's what I have tried so far:

def groups_per_user(group_dictionary):
    user_groups = {}
    groups = []
    # Go through group_dictionary
    for group,users in group_dictionary.items():
        # Now go through the users in the group
        for user in users:
        # Now add the group to the list of
          # groups for this user, creating the entry
          # in the dictionary if necessary
          groups.append(group)
          user_groups[user] = group

    return(user_groups)

print(groups_per_user({"local": ["admin", "userA"],
        "public":  ["admin", "userB"],
        "administrator": ["admin"] }))

How can I traverse throw the list and at the same time add the user to the group name as efficient as possible?

Please excuse my grammars, that's my fist question here. Thank you

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
Abdu Samaraie
  • 41
  • 1
  • 1
  • 4
  • 1
    This https://stackoverflow.com/a/485368/2947378 ? – rdas Feb 06 '20 at 17:38
  • What do you mean with "Fill in the blanks"? What blanks? – Kelly Bundy Feb 06 '20 at 17:41
  • 1. You probably dont need the `groups`list at all. 2. The values in your `user_groups` dict doesnt make sense - you are setting it to a single group, when what you probably really want is a list (or even better, a set) os the groups that user is in. 3. The logic can be further simplified by using a `defaultdict` whose value-default is a `set()`. – Tom Dalton Feb 06 '20 at 17:41

3 Answers3

8

The issue with your code is that there is only one groups list, when what you actually want is a list of groups for each user. Try this

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:
                user_groups[user] = []
            user_groups[user].append(group)
    return user_groups

Alternatively, we could replace those three lines with a setdefault call:

def groups_per_user(group_dictionary):
    user_groups = {}
    for group, users in group_dictionary.items():
        for user in users:
            user_groups.setdefault(user, []).append(group)
    return user_groups

A third option is to use a 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
Dennis
  • 2,249
  • 6
  • 12
2

Never mind guys I just solved it. all I needed is to get the group by user and concatenate it an empty list:

new code is

def groups_per_user(group_dictionary):
    user_groups = {}
    # Go through group_dictionary
    for group,users in group_dictionary.items():
        # Now go through the users in the group
        for user in users:
        # Now add the group to the the list of
          # groups for this user, creating the entry
          # in the dictionary if necessary
          user_groups[user] = user_groups.get(user,[]) + [group]

    return(user_groups)

print(groups_per_user({"local": ["admin", "userA"],
        "public":  ["admin", "userB"],
        "administrator": ["admin"] }))
Abdu Samaraie
  • 41
  • 1
  • 1
  • 4
1

Something like this?

from collections import defaultdict

def groups_per_user(group_dictionary):
    user_groups = defaultdict(set)
    for group, users in group_dictionary.items():
        for user in users:
            user_groups[user].add(group)
    return user_groups
Tom Dalton
  • 6,122
  • 24
  • 35