Short-circuit Logic

Cameron Simpson cs at zip.com.au
Sun May 26 21:57:54 EDT 2013


On 27May2013 00:40, Steven D'Aprano <steve+comp.lang.python at pearwood.info> wrote:
| On Sun, 26 May 2013 16:22:26 -0400, Roy Smith wrote:
| 
| > In article <mailman.2196.1369599562.3114.python-list at python.org>,
| >  Terry Jan Reedy <tjreedy at udel.edu> wrote:
| > 
| >> On 5/26/2013 7:11 AM, Ahmed Abdulshafy wrote:
| >> 
| >> >       if not allow_zero and abs(x) < sys.float_info.epsilon:
| >> >                  print("zero is not allowed")
| >> 
| >> The reason for the order is to do the easy calculation first and the
| >> harder one only if the first passes.
| > 
| > This is a particularly egregious case of premature optimization.  You're
| > worried about how long it takes to execute abs(x)?  That's silly.
| 
| I don't think it's a matter of premature optimization so much as the 
| general principle "run code only if it needs to run". Hence, first you 
| check the flag to decide whether or not you care whether x is near zero, 
| and *only if you care* do you then check whether x is near zero.
| 
| # This is silly:
| if x is near zero:
|     if we care:
|         handle near zero condition()
| 
| # This is better:
| if we care:
|     if x is near zero
|         handle near zero condition()
| 
| 
| Not only is this easier to understand because it matches how we do things 
| in the real life, but it has the benefit that if the "near zero" 
| condition ever changes to become much more expensive, you don't have to 
| worry about reordering the tests because they're already in the right 
| order.

I wouldn't even go that far, though nothing you say above is wrong.

Terry's assertion "The reason for the order is to do the easy
calculation first and the harder one only if the first passes" is
only sometimes that case, though well worth considering if the
second test _is_ expensive.

There are other reasons also. The first is of course your response,
that if the first test fails there's no need to even bother with
the second one. Faster, for free!

The second is that sometimes the first test is a guard against even
being able to perform the second test. Example:

  if s is not None and len(s) > 0:
    ... do something with the non-empty string `s` ...

In this example, None is a sentinel value for "no valid string" and
calling "len(s)" would raise an exception because None doesn't have
a length.

With short circuiting logic you can write this clearly and intuitively in one line
without extra control structure like the nested ifs above.

Cheers,
-- 
Cameron Simpson <cs at zip.com.au>

Who are all you people and why are you in my computer?  - Kibo



More information about the Python-list mailing list