How to write If statements for all logical conditions 2 ^ N (python)

I have a function that should execute a query based on the entered query instances. but as conditions grow, I’m bored of listing them all. For example: suppose I have two conditions:

if (cond_1 == True and cond_2 == False): do something elif cond_1 == True and cond_2 == True: do something else elif cond_1 == False and cond_2 == True: do this 

....

so I assume that if the conditions take binary values, then there are 2 ^ n operators that I should write: (

so now I have 3 condition variables (8 operators) .. and I am afraid that this number may increase in the future. Is it better to check these conditions?

+4
source share
6 answers

Do you always need to write all the features of 2 ^ n?

And all you have to do for others (same as 2 ^ n actions?)

However, I can give some tips:

Do not use '== True' or '== False'

What you wrote is:

 if cond_1 and not cond_2: do something elif cond_1 and cond_2: do something else elif not cond_1 and cond_2: do this 

Also consider writing:

 if cond_1: if cond_2: Do something else: Do something else: if cond_2: Do something else: Do something 

You can also define functions based on values:

 def __init__(self): self.actions = { (False, False): action_1, (False, True ): action_2, ... } def action_1(self): some action def action_2(self): some action .... 

and name it with:

 self.actions[(cond_1, cond_2)]() 

If you want to optimize the number of options, if you have different conditions with similar actions, take a look at Carnot Maps (this is easier than it sounds):

http://en.wikipedia.org/wiki/Karnaugh_map

+9
source

You should never test a boolean variable with == True or == False . Instead, just use boolean values. If you want to cover almost any combination of truth values, you might also want to nest, for example:

 if cond_1: if cond_2: do something else: do something else elif cond_2: do this 

If the number is larger than this, I would suggest a map, for example:

 call_map = { (True, True, True): func1, (True, False, True): func2, (True, False, False): func3, } try: func = call_map[(cond_1, cond_2, cond_3)] except KeyError: pass else: func() 

However, note that a large number of individual cases are a sure smell of code. In almost any situation, you really do not need so many cases and can actually call the function directly. You may think that your case is an exception, but most likely it is not. Why do you need a lot of cases?

+7
source

You are looking for a compact way to write truth tables. (The only other alternative is to find a way to simplify your expressions using Boolean algebra; a simplified form may not exist.) It is impossible to make it simpler than save as you type:

 def TruthTable(text): table = {} for line in text.splitlines(): line = line.strip() if line: inputs,output = line.split() table[tuple(bool(int(x)) for x in inputs)] = bool(int(output)) return lambda *inputs:table[inputs] 

Demo:

 myFunc = TruthTable(''' 000 1 001 0 010 0 011 1 100 1 101 0 110 0 111 1 ''') 

Exit:

 >>> myFunc(False, False, True) False 

If you need more logical outputs, you can adapt this to denote arbitrary expressions using, for example, a dictionary, and post-processing keys in logical tuples:

 { (0,0,0): <expr0>, (0,0,1): <expr1>, (0,1,0): <expr2>, (0,1,1): <expr3>, ... } 

You can also do this as follows with binary notation (e.g. 0b110 == 6 ), but I find it much less clean:

 { 0b000: <expr0>, 0b001: <expr1>, ... } 

You can even use the list, which you later convert to a dictionary for quick searching (by doing dict((intToBinarytuple(i),expr) for i,expr enumerate(myList)) ):

 [ # ABC <expr0>, # 000 <expr1>, # 001 <expr2>, # 010 <expr3>, # 011 ... ] 

sidenote . In the unlikely event you will need arbitrary python commands, you can send like this:

 conditions = (True, False, True) c = lambda *args: conditions==toBooleanTuple(args) if c(0,0,0): ... elif c(0,0,1): ... elif c(0,1,0): ... elif c(0,1,1): ... 
+5
source

I would use dict to more clearly display the conditions for the action. If you really need to do something different for each case, then there is probably no better way than just listing the possibilities.

 def do_something(): pass def do_something_else(): pass def do_this(): pass do_dict = {(True, False): do_something, (True, True): do_something_else, (False, True): do_this} # call it do_dict[(cond_1, cond_2)]() 
+4
source

if your goal is not to write a lot of "ands" and boolean expressions, you can use a prime number and only one condition like this (example for 2 conditions)

  cond = (2**cond_1)*(3**cond_2) 

So

 cond == 1 #means cond_1 and cond_2 are False cond == 2 #means cond_1 is True and con_2 is False cond == 3 #means cond_1 is False and con_2 is True cond == 6 #means con_1 and Con_2 are True 

This hack can be used for 3 conditions using 3 primes, etc.

+4
source

You can take an n-dimensional list of conditions and convert it to a single value for comparison, converting the conditions into sums of multiples of 2.

 >>> conditions = [True, False, True, True, False] >>> condition = sum(2**i * cond for i, cond in enumerate(conditions)) >>> condition 13 

The first value of the condition is 2^0 = 1 , the second is 2^1 = 2 , the third is 2^2 = 4 , ... which is multiplied by the value of truth (1, if True , 0, if False ).

It also lets you know if a subset of the conditions is true. If you need to know if at least a subset of the conditions is true, you can use binary & to find out:

 >>> subset = lambda c, x: (c & x) == x >>> conditions = [True, False, True, True, False, True, True, True, True] >>> condition = sum(2**i * cond for i, cond in enumerate(conditions)) >>> subset(condition, 13) True >>> subset(condition, 2) False 

In order to have the functions provided by some of the previous answers, instead of using a dictionary, you can also use both a list and a voice recorder to compare conditions with actions. You can also implement defaultdict like functionality with a list (although this uses 2 ^ n memory and probably not the best idea):

 def do_something(): print("Hello World!") condition_action_map = [None] * (2 ** len(conditions)) condition_action_map[13] = do_something 

You will probably want to comment on this if you use something like this.

+3
source

Source: https://habr.com/ru/post/1399276/


All Articles