2

So I've got this piece of code:

OPTION_1 if (i in (0, 1, 2) and j in (0, 1, 2)) else OPTION_2

It does OPTION_1 only if i and j are in the given range. I wonder if I can shorten it somehow. Tried this:

OPTION_1 if (i and j) in (0, 1, 2) else OPTION_2

But if i==4 and j==2, it does OPTION_1, despite i not being in the range.

CrazyChucky
  • 3,263
  • 4
  • 11
  • 25
Limtis
  • 95
  • 7
  • 5
    That's because `4 and 2 == 2`. – Nick Dec 08 '20 at 00:51
  • 1
    `all(map(lambda x: x in (0, 1, 2), [i, j]))` <---- it's not shorter, but if you need to consider _N_ variables instead of 2, it might help – Paul H Dec 08 '20 at 00:54
  • If you do need to scale this up to a larger number of variables you could do this trick with sets, `if len({0, 1, 2}.intersection({i, j})) == len({i, j}):` This way you are not repeatedly searching lists or tuples for values – dpwr Dec 08 '20 at 01:15
  • 1
    Does this answer your question? [Can Python test the membership of multiple values in a list?](https://stackoverflow.com/questions/6159313/can-python-test-the-membership-of-multiple-values-in-a-list) – Georgy Dec 28 '20 at 15:32

3 Answers3

6

You could use sets: the <= operator tests if all elements of the first set are elements of the second set.

OPTION_1 if {i, j} <= {0, 1, 2} else OPTION_2
kaya3
  • 47,440
  • 4
  • 68
  • 97
0

You can use the all option to check for each variable.

OPTION_1 if all(x in (0,1,2) for x in (i,j)) else OPTION_2

With this, you can check as many variables as you want or as many values you want.

OPTION_1 if all(x in range(3) for x in (a,b,c,d,e,f)) else OPTION_2

This will be equivalent to checking :

if a in (0,1,2,) and b in (0,1,2,) and c in (0,1,2,) and d in (0,1,2,) and e in (0,1,2,) and f in (0,1,2,)

The all option will check if each if statement is True. If all of them are True, then all will be set to True. It will break as soon as the first one is False. Similar to all, you can use any as well. any works when you want to check for any one of them matching the condition. Normally used when you want to use the or option.

In your if statement, you are giving the following:

if 4 and 2

In Python, 0 is false and 1 is True (any positive number greater than 0 is True).

The above statement results in: if True and True It always results the rightmost number. If the equation was a False, it will ignore the rightmost number and return False.

If condition such as if 2 and 4 will return 2

If condition such as if 4 and 2 will return 4

If condition such as if 0 and 4 will return 0

If condition such as if 4 and 0 will return 0

Your code is doing the following:

OPTION_1 if (i and j) in (0, 1, 2) else OPTION_2

Translated as:

OPTION_1 if (4 and 2) in (0, 1, 2) else OPTION_2

equates to:

OPTION_1 if (2) in (0, 1, 2) else OPTION_2

The output of this is True so resulting in OPTION_1.

Joe Ferndz
  • 8,417
  • 2
  • 13
  • 33
0

An easy and clean solution is

OPTION_1 if {i, j} < {0, 1, 2} else OPTION_2

Explanation:

If a and b are sets, then a < b tests whether a is a proper subset of b.

See Python's built-in set operators.

Asker
  • 1,299
  • 2
  • 14
  • 31