问题
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?
回答1:
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.
回答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.
回答3:
>>> 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
回答4:
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
来源:https://stackoverflow.com/questions/43032801/whats-the-value-of-short-circuit-of-python