dict to boolean expression, how to?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri Aug 1 09:28:06 EDT 2014


On Fri, 01 Aug 2014 12:45:12 +0000, Alex van der Spek wrote:

> With a dict like so:
> 
> cond = {'a': 1, 'b': 1, 'c': 1,
>         'A': 0, 'B', 0, 'C':0}
> 
> how would you make a boolean expression like this:
> 
> bool = (('a' == 1) & ('A' == 0) |
>         ('b' == 1) & ('B' == 0) |
>         ('c' == 1) & ('C' == 0))

That's False. It's always False, because 'a' does not equal 1, etc. Also, 
you're using bitwise operators & and | rather than boolean operators. 
Finally, you are shadowing the built-in bool() type, which is probably a 
bad idea.

In the first case, I think you mean cond['a'] == 1 rather than just 
'a'==1; in the second case, the bool operators are called "and" and "or"; 
and in the third case, there are many equally good names for a generic 
boolean flag, like "flag".

Putting those together, I think you probably mean something like this:

flag = (
    (cond['a'] == 1 and cond['A'] == 0) or
    (cond['b'] == 1 and cond['B'] == 0) or
    (cond['c'] == 1 and cond['C'] == 0)
    )

which can be simplified to:

flag = any( cond[c] == 1 and cond[c.upper()] for c in ['a', 'b', 'c'] )

If you *really* mean bitwise-and, you can change the "and"s to & and 
"or"s to | but honesty that's pointless and inefficient because all your 
conditions are bools, not arbitrary integers.


> The fact that lowercase and uppercase keys are stringed together with &
> is intentional albeit the actual condition is a bit more tricky.
> 
> I've tried several approaches using eval() on a string built from the
> dict but landed with just spelling it out literally.

Ayyyeee!!!! Don't use eval(). Really. Any time you think you need to use 
eval(), smash your hand with a hammer until the urge goes away.

*wink*

But seriously: if you need to ask "why not use eval?", you're not ready 
to use eval safely. But in a nutshell:

- using eval is a large performance hit (about 10 times slower);

- eval is dangerous and can introduce code injection vulnerabilities.

eval is almost never the right solution to any problem, and in the very 
few exceptions, it needs careful handling by an expert to ensure you're 
not introducing serious security bugs.


-- 
Steven



More information about the Python-list mailing list