2

I'm learning the book named Data Structures & Algorithms in Python.

On Page 12 that introduce the Logical Operators, it writes:

The and and or operators short-circuit, (I thinks it should add is called), in that they do not evaluate the second operand if the result can be determined based on the value of the first operand.

This feature is useful when constructing Boolean expressions in which we first test that a certain condition holds (such as a reference not being None), and then test a condition that could have otherwise generated an error condition had the prior test not succeeded.

I have some questions about this passage:

  • I can't understand exact meaning of the second paragraph. In C, we can use the &&(logical and) as the following expression: (i != 0) && (j / i > 0) to prevent the error of a division by zero. So then, could I use the expression (i != 0) and ( j / i > 0) in Python as C to get the same effect? Is my understanding to the passage right?

  • What's the usage of or as a short-circuit to constructing Boolean expressions as said in the second paragraph ?

  • The final question is about the grammar of had the prior test not succeeded in the second paragraph. I this it should be "an error condition that can had the prior test not succeeded", am I right?

3
  • 1
    1. You can just test it out 2. It's the same as in C 3. Your "correction" doesn't make sense to me and I doubt there's anything wrong with the grammar here Commented Mar 26, 2017 at 18:28
  • A note: Python's Boolean logical operators have lower precedence than most other operators, so you usually don't need parentheses around the expressions on either side. You can, for instance, just write i != 0 and j / i > 0. Only x if y else z expressions and lambda functions have lower precedence, and I can't even think of a way to have those usefully show up within a term of a Boolean operator (it's possible, but will almost never happen in real-word code). Commented Mar 26, 2017 at 18:44
  • Thanks for all your help. The answer to the third question is here : Conditional sentences not starting with “if”. Commented Mar 26, 2017 at 19:59

4 Answers 4

2

As I recall, short-circuit is referring to a compiler optimization. As you are already aware, in an AND conditional, the second expression is not evaluated if the first condition is false. After all, what is the point? The overall expression CANNOT be true since the first condition is already false. Similarly, with the OR logic, as soon as a single condition is true, the entire OR expression is true. This boils down to runtime savings. Expressions can be left unevaluated and thus not burn any CPU cycles.

Incidentally, I use OR short-circuits all the time in bash programming. For example, the following expression is useful for running a function if the preceeding condition is false:

[ $# -ge 2 ] || errexit "You have not supplied enough parameters"

In the above example, errexit will be called only if the command line did not have 2 arguments or more. Of course, in my example, I don't care about performance. Rather, I'm using the || short circuit logic as syntactic sugar.

And that's what it boils down to: In a tight loop, where performance matters, you can be somewhat certain that expressions will not be evaluated unnecessarily. But in the example that you described for && to avoid divide by zero, you could have just as easily written that with a nested IF statement. Again, it's a style choice more often than a performance consideration.

All that said, let me answer your questions one at a time:

I can't understand exact meaning of the second paragraph. In C, we can use the &&(logical and) as the following expression: (i != 0) && (j / i > 0) to prevent the error of a division by zero. So then, could I use the expression (i != 0) and ( j / i > 0) in Python as C to get the same effect? Is my understanding to the passage right?

You are correct.

What's the usage of or as a short-circuit to constructing Boolean expressions as said in the second paragraph ?

As I explained in detail above: performance and syntax sugar ( that is, less typing and shorter expressions; idioms ).

The final question is about the grammar of had the prior test not succeeded in the second paragraph. I this it should be "an error condition that can had the prior test not succeeded", am I right?

I agree with you that the statement could be worded better. But when you try to express it, you'll see that it is a difficult thing to do ( in fact, your suggestion is not valid ). Basically, your example of avoiding divide by zero error is a perfect example of what the author is trying to say. Here's my attempt to paraphrase: Short-circuit logic is useful to check pre-conditions of expressions that may generate errors if those conditions are not met.

Sign up to request clarification or add additional context in comments.

2 Comments

"performance and syntax sugar" is not complete because sometimes you require short circuit to avoid throwing an error. Take the example of testing the last value in a list. You need to first check if list is empty before comparing the last value in the list. mylist[-1] will throw an error when list is empty.
I think you and I could debate the terminology back and forth without a strict definition of syntax sugar. To me, the example you give is syntax sugar in as much as it could be written as an if statement as well. You may not agree with the term "syntax sugar" in this case, but you would have to agree that both the if statement and the boolean short circuit are two ways of expressing the same bit of code and it's more a matter of style than anything else.
2

I can't understand exact meaning of the second paragraph. In C, we can use the &&(logical and) as the following expression: (i != 0) && (j / i > 0) to prevent the error of a division by zero. So then, could I use the expression (i != 0) and ( j / i > 0) in Python as C to get the same effect? Is my understanding to the passage right?

Yes

What's the usage of or as a short-circuit to constructing Boolean expressions as said in the second paragraph ?

As an example:

if (y is None) or (x not in y):

where y is either a list of things or None which in this case we want to treat a bit like an empty list, but x not in None would be an error.

Or:

(i  == 0) or (j / i > 0)

The final question is about the grammar of had the prior test not succeeded in the second paragraph. I this it should be "an error condition that can had the prior test not succeeded", am I right?

No, your phrasing is not correct grammar.

If you have X and/or Y, X is the first or 'prior' test, Y is the second, and it's possible that X is false and trying to evaluate Y will cause an error.

Comments

1

There is another reason -- syntactic correctness -- to use short circuit. Getting an item from a list for comparison without throwing an error on empty list condition is an important reason to use short circuiting as shown below. There are other ways to handle empty list, but such code would be more complex (more lines of code).

In this example, the application requirement is to behave differently strictly when 'bob' is the last list item. Bob is required to not be last in our list! (Because Bob is the best, that's all.)

The three lines of code shown below that have conditional expressions with the "or" in them do not throw an error.

>>> a = []
>>> a[-1] == 'bob'  # is the last one 'bob'?
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>> a[-1:][0] == 'bob'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>> len(a)
0
>>> len(a)==0 or a[-1] != "bob"
True
>>> a.append('bob')
>>> len(a)==0 or a[-1] != "bob"  # the last one is bob. Act different.
False
>>> a.append('news')
>>> len(a)==0 or a[-1] != "bob"
True

Comments

0
>>> if 1 or 0:
...     print "I am learning"
... 
I am learning
>>> if 1 and 0:
...     print "I am learning"
... 
>>> if 0:
...     print "I am learning"
... 
>>> if 1:
...     print "I am learning"
... 
I am learning
>>> if None and 1:
...     print "be crazy"
... 
>>> if None or 1:
...     print "be crazy"
be crazy

much like C implementation.

And the last line is read correct had the first condition was unsuccessful in returning the error the second condition checks for the error

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.