什么是Python的短路价值?

时间:2017-03-26 18:23:41

标签: python logical-operators short-circuiting

我正在学习名为 Data Structures& amp; Python中的算法

在介绍逻辑运算符的第12页上,它写道:

  

以及运营商短路,(我认为应该添加称为),如果可以根据第一个操作数的值确定结果,则它们不会计算第二个操作数。

     

此特性在构造布尔表达式时非常有用,我们首先测试某个条件是否成立(例如引用不是None),然后测试一个可能产生错误条件的条件具有先验条件测试未成功

我对这段话有些疑问:

  • 我无法理解第二段的确切含义。在C中,我们可以使用&& (逻辑)作为以下表达式: (i != 0) && (j / i > 0)以防止除法误差为零。那么,我可以使用Python中的表达式(i != 0) and ( j / i > 0)作为C来获得相同的效果吗?我对这段经文的理解是对的吗?

  • 使用作为短路来构建第二段所述的布尔表达式是什么?

  • 最后一个问题是关于第二段中先前测试未成功的语法。我这应该是"一个错误的情况,可以让先前的测试没有成功",我是对的吗?

4 个答案:

答案 0 :(得分:2)

  

我无法理解第二段的确切含义。在C中,我们可以   使用&&(logical和)作为以下表达式:(i!= 0)&& (j /   我> 0)防止除法误差为零。那么,我可以   使用Python中的表达式(i!= 0)和(j / i> 0)作为C来获取   同样的效果?我对这段经文的理解是对吗?

  

什么是   使用或作为短路来构造布尔表达式   在第二段中说过?

举个例子:

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

其中y是一个事物列表或None,在这种情况下,我们希望将其视为空列表,但x not in None将是一个错误。

或者:

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

最后一个问题是关于语法   如果先前的测试在第二段中没有成功。我知道了   应该是“错误条件,可以事先测试不   成功了“,我是对的吗?

不,你的措辞语法不正确。

如果你有X and/or YX是第一个或'先前'的测试,Y是第二个,X可能是假的并且试图评估Y会导致错误。

答案 1 :(得分:2)

我记得,短路指的是编译器优化。如您所知,在AND条件中,如果第一个条件为false,则不评估第二个表达式。毕竟,重点是什么?由于第一个条件已经为假,因此整体表达式不能为真。类似地,使用OR逻辑,只要单个条件为真,整个OR表达式就为真。这归结为运行时节省。表达式可以不被评估,因此不会烧掉任何CPU周期。

顺便说一下,我在bash编程中一直使用OR短路。例如,如果前面的条件为false,则以下表达式对于运行函数很有用:

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

在上面的示例中,仅当命令行没有2个或更多参数时才会调用errexit。当然,在我的例子中,我并不关心性能。相反,我正在使用||短路逻辑作为语法糖。

这就是它归结为:在紧密的循环中,性能很重要,你可以确定表达式不会被不必要地评估。但是在你为&&和为了避免除以零,你可以用嵌套的IF语句轻松编写。同样,这是一种风格选择,而不是性能考虑。

所有这一切,让我一次一个地回答你的问题:

  

我无法理解第二段的确切含义。在C中,我们可以使用&&(logical和)作为以下表达式:(i!= 0)&&   (j / i> 0)以防止除法误差为零。那么,可以   我在Python中使用表达式(i!= 0)和(j / i> 0)作为C来获取   同样的效果?我对这段经文的理解是对吗?

你是对的。

  

如第二段所述,构造布尔表达式的用法或短路是什么?

正如我在上面详细解释的那样:性能和语法糖(即减少输入和缩短表达式;成语)。

  

最后一个问题是关于先前测试没有的语法   在第二段中取得了成功。我这应该是“一个错误   可以让先前的测试没有成功的条件“,我是对的吗?

我同意你的说法可能措辞得更好。但是当你试图表达它时,你会发现它很难做到(实际上,你的建议是无效的)。基本上,你避免被零除错误的例子就是作者试图说的一个完美的例子。这是我试图解释:短路逻辑对于检查表达式的前提条件非常有用,如果不满足这些条件,则可能会产生错误。

答案 2 :(得分: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

很像C实现。

如果第一个条件在第二个条件检查错误时返回错误不成功,则读取最后一行

答案 3 :(得分:0)

还有另一个原因-语法正确性-使用短路。从列表中获取项目进行比较而不在空列表条件下引发错误是使用短路的重要原因,如下所示。还有其他方法可以处理空列表,但是这样的代码会更复杂(代码行更多)。

在此示例中,当“ bob”是最后一个列表项时,应用程序要求严格执行不同的行为。鲍勃必须不在我们的名单上! (因为鲍勃是最好的,仅此而已。)

下面显示的三行代码中带有条件表达式(其中带有“或”)的内容不会引发错误。

>>> 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