I need to create a list of blocked users by key. Each user has several attributes, and if any of these attributes is in the keys, the user is blocked.
I wrote the following nested for-loop, and it works for me, but I want to write it in a more pythonic way with fewer lines and a more readable way. How can i do this?
for
for key in keys: key.blocked_users = [] for user in get_users(): for attribute in user.attributes: for key in keys: if attribute.name == key.name: key.blocked_users.append(user)
, , Python. , , - , ?:)
, . , "". , ( ) ( ) :
for key in keys: key.blocked_users = [] keyname_map = {key.name: key.blocked_users for key in keys} # map the key name to blocked_user list keynames = set(keyname_map)
set(keyname_map) - , , .
set(keyname_map)
set.intersection, , :
set.intersection
for user in get_users(): for key in keynames.intersection({attribute.name for attribute in user.attributes}): keyname_map[key].append(user)
set.intersection .
, attribute.name key.name .
attribute.name
key.name
for -loop:
for key in keys: keyname = key.name key.blocked_users = [user for user in get_users() if any(attribute.name == keyname for attribute in user)]
, for , , . , .
, , , .
for "" , itertools.product. :
itertools.product
>>> from itertools import product >>> a = [1, 2] >>> b = [3, 4] >>> c = [5] >>> for x in product(a, b, c): x ... (1, 3, 5) (1, 4, 5) (2, 3, 5) (2, 4, 5)
, Pythonic, - :
[key.blocked_users.append(user) for key in keys for attribute in user.attributes for user in get_users() if attribute.name == key.name]