Home > OS >  Look through a list to find unwanted combination
Look through a list to find unwanted combination

Time:10-01

I am still quite new to python so bear with me. I have a list of users, along with the roles that they are holding on to:

Role = [('Amy', 'Administrator'), 
        ('Brandon', 'Editor'), 
        ('Brandon', 'User'),
        ('Eric', 'User'), 
        ('Brandon', 'Administrator'), 
        ('Eric', 'Administrator')]

I also have another list of combinations that a user should not have:

Unwanted = [('Administrator', 'Editor'), 
            ('Administrator', 'User'), 
            ('Editor', 'User')]

The code should identify the unwanted combination that a user have

["Brandon:('Administrator', 'Editor')", "Brandon:('Administrator', 'User')", "Brandon:('Editor', 'User')", "Eric:('Administrator', 'User')"]

The code that I have tried:

Role.sort()
 
res = [list(i) for j, i in groupby(Role,
              lambda a: a[0])]

res.sort()

temp = []
results =[]

for x in res:
    for y in x:
        temp.append(y[1])
        name = y[0]
        for z in Unwanted:
                if z[0] and z[1] in temp:
                    results.append(y[0]   ":"   str(z))
                    break
        temp.clear()
print(results)

["Brandon:('Administrator', 'Editor')", "Brandon:('Administrator', 'User')", "Eric:('Administrator', 'User')"]

Which part am I missing that is causing this value to be omitted: "Brandon:('Editor', 'User')"

CodePudding user response:

Try the below

from collections import defaultdict

data = defaultdict(list)
roles = [('Amy', 'Administrator'), 
        ('Brandon', 'Editor'), 
        ('Brandon', 'User'),
        ('Eric', 'User'), 
        ('Brandon', 'Administrator'), 
        ('Eric', 'Administrator')]

unwanted_lst = [('Administrator', 'Editor'), 
            ('Administrator', 'User'), 
            ('Editor', 'User')]
for role in roles:
    data[role[0]].append(role[1])
for user,roles in data.items():
    for unwanted in unwanted_lst:
        if unwanted[0] in roles and unwanted[1] in roles:
            print(f'{user} has unwanted roles {unwanted}')

output

Brandon has unwanted roles ('Administrator', 'Editor')
Brandon has unwanted roles ('Administrator', 'User')
Brandon has unwanted roles ('Editor', 'User')
Eric has unwanted roles ('Administrator', 'User')

CodePudding user response:

if z[0] and z[1] in temp: translates to if z[0] == True and z[1] in temp

For that reason, your code currently just prints everyone with user or editor in the second slot

Another issue is that temp.clear() is indented too far, so it clears the list after each addition.

from itertools import groupby

Role = [('Amy', 'Administrator'), 
        ('Brandon', 'Editor'), 
        ('Brandon', 'User'),
        ('Eric', 'User'), 
        ('Brandon', 'Administrator'), 
        ('Eric', 'Administrator'),
        ('John', 'User')]


Unwanted = [('Administrator', 'Editor'), 
            ('Administrator', 'User'), 
            ('Editor', 'User')]

Role.sort()
 
list_of_list_of_user_roles = [
    list(i) 
    for _, i in groupby(
        Role, lambda a: a[0]
    )
]

list_of_list_of_user_roles.sort()

user_roles = []
results =[]

for list_of_user_roles in list_of_list_of_user_roles:
    for user, role in list_of_user_roles:
        user_roles.append(role)
        for unwanted_role_1, unwanted_role_2 in Unwanted:
                if unwanted_role_1 in user_roles and unwanted_role_2 in user_roles:
                    results.append(user   ":"   unwanted_role_1   ","   unwanted_role_2)
                    break
    user_roles.clear()
print(results)
  • Related