5

Python short circuits the logical operators. for eg:

if False and Condition2:
    #condition2 won't even be checked because the first condition is already false.

Is there a way to stop this behavior. I want it to check both the conditions and then perform the and operation(as done in c, c++ etc). It's useful when we are performing some operation along with the condition. e.g.:

if a < p.pop() and b < p.pop():

One way can be checking the conditions before and then comparing the Boolean values. But that would be wastage of memory.

7
  • 2
    I guarantee that the "wasted" memory here will not affect your program in any way whatsoever. Commented Oct 3, 2017 at 8:52
  • wastage of memory, not sure how memory is being wasted here. Commented Oct 3, 2017 at 8:52
  • Bad workaround: (a<p.pop()) == (b<p.pop()) == True. Good workaround: Split your if statement into multiple lines. Commented Oct 3, 2017 at 8:55
  • You seem to come from the C area of coding and you are trying to bring C paradigms into Python which might work but might also be considered as anti-patterns. A side effect on a condition check would be such an anti-pattern in Python. Commented Oct 3, 2017 at 9:01
  • 3
    The C language does "short-circuiting" too. Commented Oct 3, 2017 at 9:16

4 Answers 4

10
if all([a < p.pop(), b < p.pop()])

This creates a list, which will be evaluated in its entirety, and then uses all to confirm that both values are truthy. But this is somewhat obscure and I'd rather suggest you write plain, easy to understand code:

a_within_limit = a < p.pop()
b_within_limit = b < p.pop()
if a_within_limit and b_within_limit:
Sign up to request clarification or add additional context in comments.

Comments

2

If the conditions are booleans, as they are in your example, you could use & instead:

>>> a, b, p = 1, 1, [0, 0]
>>> (a < p.pop()) & (b < p.pop())
False
>>> p
[]

Comments

2

You can use the all() and any() built-in functions to somehow emulate the and and or operators. Both take an iterable of boolean-likes values as parameter. If you give it a literal tuple or list, all members will be fully evaluated:

# all emulates the and operator
if all((False, Condition2)):
    do_stuff()


# any emulates the or operator
if any((False, Condition2)):
    do_stuff()

Comments

0

Short answer: No, you cannot stop it to do this.

For example:

av = p.pop()
bv = p.pop()
if a < av and b < bv:
    pass

Or:

av, bv = p.pop(), p.pop()
if a < av and b < bv:
    pass

Also, there is no waste of memory in these examples. In Python, almost everything is done by reference. The value object being popped already exists somewhere. Even the scalars like strings, ints, etc are objects (some of them are slightly optimized). The only memory changes here are (1) the creation of a new variable that refers to the same existing object, and (2) removal of the record in the dict at the same time (which referred to that object before popping). They are of the similar scale.

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.