5

我被困在这个特殊的例子中,从潜入 python

例 4.18。当与或技巧失败时

>>>>a = ""
>>>>b = "second"
>>>1 and a or b
>>>>'second'

由于 a 是一个空字符串,Python 在布尔上下文中认为它为 false,因此 1 和 '' 评估为 '',然后 '' 或 'second' 评估为 'second'。哎呀!那不是你想要的。与 - 或技巧,bool 和 a 或 b,不会像 C 表达式 bool 那样工作?a : b 当 a 在布尔上下文中为假时。

为什么它说这不是用户想要的,我的意思是 1 和 "" 将评估为 False,而 "" 或 b 将评估为 "second",这完全是应该发生的,我不明白为什么会这样错了吗?我错过了什么吗?

4

4 回答 4

4

不,你没有错过什么。

内联条件在PEP 308expr if cond else expr中被引入 Python 2.5 ;在此之前,条件必须是完整的形式

if cond:
    expr
else:
    expr

然而,人们注意到,expr and cond or expr只要第一个表达式碰巧评估为布尔值 true,这种方式就可以作为内联条件。由于 Python 中的大多数事情都是正确的,因此这种语法通常会起作用——当然,有时也会失败。这实际上是添加“正确”内联条件的动机。

于 2012-05-24T16:55:17.803 回答
2

“and-or 技巧”用于模拟三元条件运算符condition ? if-true : if-false或类似运算符。由于在布尔上下文1中等价True于,因此表达式应为 yield a,而不是b。所以,教训是,不要使用 and-or 技巧。Python 从 2.5 开始就有三元条件:

true if condition else false
于 2012-05-24T16:55:32.133 回答
2

Dive into python 不是一个好的教程,不应该遵循


x and y or z表达式在 python 具有适当的三元表达式 ( y if x else z) 之前使用。本节说明如果您期望它表现得像 C 那样,为什么它会让您感到惊讶x ? y : z


python wiki上有一个教程列表。这可能会给你一个更新的资源。

于 2012-05-24T16:57:58.700 回答
0

为什么它说这不是用户想要的,我的意思是 1 和 "" 将评估为 False,而 "" 或 b 将评估为 "second",这完全是应该发生的,我不明白为什么会这样错了吗?我错过了什么吗?

我觉得这部分问题被忽略了。condition and if-true or if-false如其他答案中所述,是在 >2.5 版本中使用的技巧,以模仿其他语言condition ? if-true : if-false或更高版本if-true if condition else if-false

它的问题是,如果if-true是一个评估为假的对象(、、、""或)[],那么这将失败(),正如您查看评估时所预期的那样,但如果动态设置并且可以评估,则可能会作为错误潜入为假。False0if-true

的天真预期结果condition and a or b将是a( "", 空字符串) 的内容,因为条件 ( 1) 计算结果为true,但1 and a计算结果为 ,false因此您得到 的内容b

此问题的解决方案是使用 Python 2.5+ 语法 ( if-true if condition else if-false) 或确保它if-true永远不会为假。完成第二种方法的一种方法是将if-true和打包if-false在一个元组或列表中,因为非空可迭代始终为真:

>>> a = ""
>>> b = "second"
>>> condition = 1
>>> condition and a or b
'second'

>>> condition and [a] or [b]
['']

>>> (condition and [a] or [b])[0]
''

这是一种丑陋的解决方案,但如果您需要针对旧版本的 Python,它就在那里。

于 2012-05-24T17:57:50.933 回答