Is there a faster way of evaluating every combination of booleans in an if statement in python?

Question:

If I have 4 booleans e.g

if ((a(x) == True) and (b(x) == True) and (c(x) == True) and (d(x) == True)

then I want to do something different for each combination including when only 3 of them are true (including which ones), 2…, then only each 1… etc…

Is there a quicker way than writing a bunch of elifs?

Possibly using a loop

Asked By: Primo4151

||

Answers:

You can count the number of True booleans using arithmetic operators

numTrue = (a(x) == True) + (b(x) == True) + (c(x) == True) + (d(x) == True)
if numTrue==4:
    # foo
elif numTrue==3:
    # bar
elif numTrue==2:
    # ...
elif numTrue==1:
    #...
else:
    # ...

Note that I kept your redundant structure x==True, which, from a boolean point a view is just a convoluted version of x. But at least, now, I am sure that your booleans (since I know nothing of a(x) and others) are True or False, not other truthiness are falseness.

Answered By: chrslg

You could build a lookup table using a dict:

lookup = {(True, True, True, True): func_1,
          (True, True, True, False): func_2,
          (True, True, False, True): func_3,
          ... etc.
         }
func = lookup[a(x), b(x), c(x), d(x)]
func()
Answered By: Peter Wood

including when only 3 of them are true

This suggests you’d like to know that N of the 4 values are true:

vals = a(x), b(x), c(x), d(x)
num_true = sum(map(bool, vals))

Given such a vector of booleans, there are 2 ** 4 == 16 possibilities.
We can put 16 values into a dict named d and go from there.

k = " ".join(map(str, map(int, map(bool, vals))))
print(d[k])

If the identities don’t matter to you,
then sort so we have fewer than 16 possibilities:

k = " ".join(sorted(map(str, map(int, map(bool, vals)))))
Answered By: J_H

The solution with the lookup table is great but if you wanted to do something that takes less memory and around the same speed. You can use the if statement results to build on each other this way you’d only have 2^4(16) cases i.e:

if (a(x)):
    if(b(x):
        if(c(x)):
            if(d(x)):
                #do x
            else:
                #do y
        else:
            if (d(x)):
                #do z
            else:
                #do w
         #...
Answered By: Sriram M.