needs_eval = "((abc or def) and ghi)"
dict_group = {abc: ['[email protected]', '[email protected]', '[email protected]'], def: ['[email protected]', '[email protected]', '[email protected]'], ghi: ['[email protected]', '[email protected]', '[email protected]', '[email protected]']}
for k,v in dict_group.iteritems():
str_v=str(v[0])
needs_eval = needs_eval.replace("and", "&").replace("or", "|").replace(k,str_v)
#needs_eval = re.sub(k,v[0],needs_eval)
print(list(eval(needs_eval)))
O/p i get: ((['[email protected]', '[email protected]', '[email protected]'] | ['[email protected]', '[email protected]', '[email protected]']) & ['[email protected]', '[email protected]', '[email protected]', '[email protected]'])
When i evaluate "needs_eval" i want the logical output "['[email protected]', '[email protected]', '[email protected]']"
I am converting the dict "value" into a string before substituting it into the "needs_eval" string because "replace or re.sub" only passes strings.
2 Answers 2
The operators | and & are only defined on set not list, so you need to change your dict_group to be a dictionary of sets, e.g.:
needs_eval = "((abc or def) and ghi)"
dict_group = {'abc': {'[email protected]', '[email protected]', '[email protected]'},
'def': {'[email protected]', '[email protected]', '[email protected]'},
'ghi': {'[email protected]', '[email protected]', '[email protected]', '[email protected]'}}
>>> for k,v in dict_group.items():
... needs_eval = needs_eval.replace("and", "&").replace("or", "|").replace(k,str(v))
>>> list(eval(needs_eval))
['[email protected]', '[email protected]', '[email protected]']
Not sure why you need to convert to a list if all you need is the set of values that meet the conditions:
>>> eval(needs_eval)
{'[email protected]', '[email protected]', '[email protected]'}
1 Comment
I don't think the 'AND's and 'OR's are doing what you thing they are when comparing lists.
After playing around with this (never knew this wasn't a syntax error before just now) and reading this post, it appears that:
AND with two lists that evaluate to True returns the right operand
OR with two lists that evaluate to True returns the left operand
Because you're lists have items, they'll always evaluate to True. Your output is only happening because of the order in which you apply (and group) the 'AND's and 'OR's to your lists.
The gnarly bug that will inevitably bit you is - if you attempt to iterate the dictionary to generate your list values, you will get non-deterministic behavior. This is because dictionaries do not guarantee order, so sometimes you'll get different output for "no apparent reason".
I would strong suggest to not rely on the 'and' and 'or' operators for your lists.
3 Comments
and and or to & and |, which are defined on sets. And does give the answer expected...
[email protected]in the expected output?eval? This seems like the paramount of an xy problem. What are you actually trying to do? I have a strong inkling that there's a better solution thaneval...