(Python) Split dictionary into two based on property
I want to split the dictionary in two depending on if any array of strings is present in a property in the main dictionary. Currently I can achieve this with two separate verbal concepts (see below), but is there a more efficient way to do this with only one string / dictionary comprehension?
included = {k:v for k,v in users.items() if not any(x.lower() in v["name"].lower() for x in EXCLUDED_USERS)}
excluded = {k:v for k,v in users.items() if any(x.lower() in v["name"].lower() for x in EXCLUDED_USERS)}
EDIT
EXCLUDED_USERS
contains a list of templates.
source to share
One line solution (with lower_excluded_users
which I could not resist)
included, excluded = dict(), dict()
# ssly, you don't have to do this everytime
lower_excluded_users = [x.lower() for x in EXCLUDED_USERS]
# and now the one-line answer using if-else-for construct with
# v substituted by D[k]. And instead of using `for k, v in dicn.items()`
# I have used [... for aKey in dicn.keys()]
[ excluded.update({aKey: users[aKey]}) \
if any(x in users[aKey]["name"].lower() for x in lower_excluded_users) \
else \
included.update({aKey: users[aKey]}) \
for aKey in users.keys()
]
Or one without improvement:
[excluded.update({aKey: users[aKey]}) if any(x in users[aKey]["name"].lower() for x in lower_excluded_users) else included.update({aKey: users[aKey]}) for aKey in users.keys()]
source to share
This solution is more verbose, but should be more efficient, and possibly more readable:
included = {}
excluded = {}
lower_excluded_users = [x.lower() for x in EXCLUDED_USERS]
for k,v in users.items():
if any(x in v["name"].lower() for x in lower_excluded_users):
excluded[k] = v
else:
included[k] = v
I don't think it can be done with one understanding. You k:v
can use a three-dimensional operator in , you cannot use else
after if
in a template {k:v for k,v in users.items() if k ...}
.
source to share