How to stop short circuiting in Python? [duplicate]
Asked Answered
X

4

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.

Xymenes answered 3/10, 2017 at 8:49 Comment(7)
I guarantee that the "wasted" memory here will not affect your program in any way whatsoever.Candlewick
wastage of memory, not sure how memory is being wasted here.Harem
Bad workaround: (a<p.pop()) == (b<p.pop()) == True. Good workaround: Split your if statement into multiple lines.Jebel
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.Saccharate
My apologies. I didn't mean wastage of memory. I just didn't want to use extra variables. ThanksXymenes
@KlausD. Yes. I'm learning that on my way. :)Xymenes
The C language does "short-circuiting" too.Wingard
A
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:
Alpha answered 3/10, 2017 at 8:55 Comment(0)
G
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()
Guava answered 3/10, 2017 at 8:55 Comment(0)
A
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
[]
Azotic answered 3/10, 2017 at 9:3 Comment(0)
P
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.

P answered 3/10, 2017 at 8:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.