Is it safe to replace '==' with 'is' to compare Boolean-values
我做了几个布尔比较:
1 2 3 4
| >>> (True or False) is True
True
>>> (True or False) == True
True |
听起来像==和is可以互换布尔值。
有时候使用is会更清楚
我想知道:
是否在python中预先分配了True和False?
bool(var)是否始终使用预先分配的True(或False)返回相同的True(或False)?
用is替换==来比较布尔值是否安全?
这不是最佳实践。
我只是想知道真相。
你可能不需要比较布尔值。如果你做的事情如下:
1 2
| if some_bool == True:
... |
......只需将其更改为:
不需要is或==。
正如评论者指出的那样,有正当理由来比较布尔值。如果两个布尔值都是未知的并且您想知道一个是否与另一个相等,则应使用==或!=而不是is或is not(原因如下所述)。请注意,这在逻辑上等效于xnor和xor,它们在Python中不作为逻辑运算符存在。
在内部,应该只有两个布尔文字对象(另请参阅C API),对于任何Python程序,如果bool(x) == True,bool(x) is True应该是True。两个警告:
-
然而,这并不意味着x is True if x == True(例如x = 1)。
-
这适用于Python(CPython)的常规实现,但在其他实现中可能不适用。因此==是更可靠的比较。
-
@detly,答案都没有。甚至kevpie都没有说明True和False是唯一的实例,还是真的有任何文档。你的可能是最实用的。
-
@Matthew @detly:对不起,经过反思,我不应该投票,而只是留下评论。似乎大多数人都想象"True == True"作为" == True"的替身,在这种情况下我们应该按照建议编写""。但这错过了(在我看来很明显)"True == True"实际上是"<我的第一个表达式> == <我的第二个表达式>"的替身,这是一个非常有效的写法。我无法撤消我的downvote。不过我还是觉得原来(未经编辑)的答案很糟糕。
-
@Mitch Schwartz - 好吧,这让事情更加清晰。顺便说一下,你应该能够在编辑答案后立即撤销downvote,但如果没有,那就没什么大不了的。
-
@detly:哦,你是对的。我忘了编辑会影响5分钟的窗口。由于编辑而改为upvote,因为我最初处理它的方式感觉不好。
-
在某些情况下,您需要比较布尔值,例如在比较时未知布尔值。当您将布尔值解释为信息位而不是真值时,这种需求很容易出现,并且与xor运算符^完全一样有效。
-
@ user1747134是的,使用!=代替xor是一个非常有用的技巧!
-
@ user1747134我想我已经解决了你的反馈意见。
-
@detly,我使??用 is True&amp; is False有时,作为低成本的输入验证技术(除了实际的输入验证功能。)你在答案中说"可能不应该",你能看到这个用例有什么问题吗?
-
您可能想要比较布尔值的一种情况是使用Django的BooleanField,其值可以是None。对于带有字段my_bool的名为my_model的模型,无论字段值是False还是None,语句if not my_model.my_bool都将执行,如果语句读取if my_model.my_bool == False则不会发生。有点明显,与所有场景无关,但值得考虑。
留意你可能会比较的其他内容。
1 2 3 4
| >>> 1 == True
True
>>> 1 is True
False |
True和False将在python实例中为其生命周期提供稳定的对象ID。
1 2 3 4
| >>> id(True)
4296106928
>>> id(True)
4296106928 |
is比较对象的id
编辑:添加or
由于OP正在使用or,因此可能值得指出这一点。
或者评估为True:返回第一个'True'对象。
1 2 3 4 5 6
| >>> 1 or True
1
>>> 'a' or True
'a'
>>> True or 1
True |
或者评估False:返回最后一个'False'对象
1 2 3 4
| >>> False or ''
''
>>> '' or False
False |
并且计算结果为True:返回最后一个'True'对象
1 2 3 4
| >>> True and 1
1
>>> 1 and True
True |
并且计算结果为False:返回第一个'False'对象
1 2 3 4
| >>> '' and False
''
>>> False and ''
False |
这是一个重要的python习惯用法,它允许简洁而紧凑的代码来处理常规python对象上的布尔逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| >>> bool([])
False
>>> bool([0])
True
>>> bool({})
False
>>> bool({False: False})
True
>>> bool(0)
False
>>> bool(-1)
True
>>> bool('False')
True
>>> bool('')
False |
基本上'空'对象是假的,'非空'是真的。
将其与@ detly和其他答案相结合,可以提供一些有关如何在python中使用if和bools的见解。
-
bool(1)为True ==> True
-
对。 bool(1) ==> True所以bool(1) is True ==> True。当您必须具有相同的对象实例时,应该使用。
是。保证恰好有两个bool s,True和False:
Class bool cannot be subclassed
further. Its only instances are False
and True.
这意味着如果您知道两个操作数都是bool,则==和is是等效的。但是,正如det det地说,在这种情况下通常没有理由使用。
似乎所有答案都处理解释器启动后定义的True和False。在布尔值成为Python的一部分之前,它们通常被定义为程序的一部分。即使是现在(Python 2.6.6),它们只是可以指向不同对象的名称:
1 2 3 4 5 6 7
| >>> True = 1
>>> (2 > 1)
True
>>> (2 > 1) == True
True
>>> (2 > 1) is True
False |
如果您必须处理旧软件,请注意这一点。
==和is都是比较运算符,它们将返回一个布尔值 - True或False。 True的数值为1,False的数值为0。
运算符==比较两个对象的值和比较的对象通常是相同的类型(int vs int,float vs float),如果比较不同类型的对象,则它们是不相等的。运算符is测试对象标识,如果x和y具有相同的id,则'x is y'为真。也就是说,它们是相同的对象。
因此,当您比较相同类型的返回值时,使用==并且如果您要比较两个对象是否相同(无论是布尔值还是其他任何对象),您可以使用is。
42 is 42为True且与42 == 42相同。
-
你的最后一个断言是错误的。 42是42是真并且与42 = 42不相同。is用于身份比较,并且恰好有时两个数字具有相同的id(出于优化原因)。测试:256 is (255+1) == True和256 is (255+1) == False(python版本之间的限制可能不同)。
-
谢谢你的评论。但是你的最后一个表达式有点困惑(256是(255 + 1))== True;返回true
-
好吧,我认为在你的情况下可以应用"(python版本之间的限制可能不同)"。如果你使用更大的数字进行测试,你将在某个时刻得到False,数字之间的身份相等性与python优化有关......这里:stackoverflow.com / a / 366353/687989是关于该问题的解释。
==运算符测试相等性是对象标识的关键字测试。我们是否在谈论同一个对象。注意,更多变量可以引用同一个对象。