1

Is it possible to implement the assignment of a variable to the value of the logical "and" or "or"? and use them in a comparison expression?

logical_obj = bool() if True: logical_odj = or else: logical_obj = and if 1 + 2 == 3 logical_obj 3 + 1 == 5: pass 
5
  • This isn't exactly a duplicate of the marked question as operator does not expose functions for and or or. In a pinch bitwise operators could be used, but that would probably justify an answer. Commented Apr 10, 2020 at 0:59
  • 1
    See: stackoverflow.com/questions/7894653/… Commented Apr 10, 2020 at 1:00
  • 2
    1 or 3 == 4 probably isn't what you want anyway, but 1 == 4 or 3 == 4. Commented Apr 10, 2020 at 1:04
  • In that case, you probably want to use any([1 == 4, 3==4]) or all([1==4, 3==4]), as desired. Commented Apr 10, 2020 at 1:05
  • (And you can assign the functions any and all to a variable.) Commented Apr 10, 2020 at 1:13

3 Answers 3

2

and and or are operators, like + and -, and cannot be assigned to variables. Unlike + et al., there are no functions that implement them, due to short-circuting: a and b only evaluates b if a has a truthy value, while foo(a, b) must evaluate both a and b before foo is called.

The closest equivalent would be the any and all functions, each of which returns true as soon as it finds a true or false value, respectively, in its argument.

>>> any([1+2==3, 3+1==5]) # Only needs the first element of the list True >>> all([3+1==5, 1+2==3]) # Only needs the first element of the list False 

Since these are ordinary functions, you can bind them to a variable.

if True: logical_obj = any else: logical_obj = all if logical_obj([1 + 2 == 3, 3 + 1 == 5]): pass 

The list has to be fully evaluated before the function can be called, but if the iterable is lazily generated, you can prevent expressions from being evaluated until necessary:

>>> def values(): ... yield 1 + 2 == 3 ... print("Not reached by any()") ... yield 3 + 1 == 5 ... print("Not reached by all()") ... >>> any(values()) True >>> all(values()) Not reached by any() False 
Sign up to request clarification or add additional context in comments.

Comments

0

No it's not possible as these are operators but you can wrap them to a function which will then be always same:

def logical_op(cond, a, b): if cond: return a or b else: return a and b` if logical_op(True, val1, val2) == expected: ... 

or depending on your code you can apply De Morgan's law and convert and to or (and vice versa) by negation.

Comments

0

This is a bit of a doozy. One possible analogue replicates the short circuiting by also implementing lazy evaluation. This means the second argument must be converted to a function; a and b would convert into sc_and(a, lambda: b).

def sc_and(value, alternative_function): if value: return alternative_function() else: return value 

Iterators are Python's native means of performing such lazy evaluation, so you can use the shortcut in any and all using e.g. generator expressions:

t1s = (1, 3) # + t2s = (2, 1) # == rhs = (3, 5) any(t1+t2==rh for (t1,t2,rh) in zip(t1s,t2s,rhs)) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.