Python:将空字符串与 False 进行比较是 False,为啥?
Posted
技术标签:
【中文标题】Python:将空字符串与 False 进行比较是 False,为啥?【英文标题】:Python: Comparing empty string to False is False, why?Python:将空字符串与 False 进行比较是 False,为什么? 【发布时间】:2016-12-22 16:41:37 【问题描述】:如果not ''
的计算结果为True
,为什么'' == False
的计算结果为False
?
例如,与 False
相比,其他类型的“空心”(例如 0、0.0)将返回 True
:
>>> 0 == False
True
>>> 0.0 == False
True
谢谢
【问题讨论】:
空序列计算结果为False
,但不等于False
。在此处阅读:***.com/a/9573259/6313992(前 2 个答案涵盖此)
谢谢。尽管如此,我的问题仍然存在:为什么?
@TonyPower 因为这就是选择 Python 来实现的方式。 “为什么”这个问题没有真正的答案。另外,为什么空列表等于 为 False?它仍然是一个列表,只是一个空列表。
【参考方案1】:
在布尔运算的上下文中,以及当控制流语句使用表达式时,以下值被解释为 false:
False
、None
、所有类型的数字零以及空字符串和容器(包括字符串、元组、列表、字典、集合和冻结集)。所有其他值都被解释为 true。用户定义的对象可以通过提供__bool__()
方法来自定义它们的真值。运算符
not
如果其参数为假则产生True
,否则产生False
。https://docs.python.org/3/reference/expressions.html#comparisons
但是:
运算符
<
、>
、==
、>=
、<=
和!=
比较两个对象的值。对象不需要具有相同的类型。...
因为所有类型都是
object
的(直接或间接)子类型,它们从object
继承默认比较行为。类型可以通过实现诸如__lt__()
等丰富的比较方法来自定义它们的比较行为...https://docs.python.org/3/reference/expressions.html#boolean-operations
所以,技术实现的答案是它的行为方式是因为not
和==
使用不同的比较。 not
使用__bool__
,一个对象的“真值”,而==
使用__eq__
,一个对象与另一个对象的直接比较。因此,可以询问一个对象是否认为自己是 truthy 或 falsey,并与此分开询问它是否认为自己与另一个对象相等。其默认实现以这样一种方式排列,即两个对象都可以认为自己 falsey 但不认为自己彼此相等。
【讨论】:
【参考方案2】:''
和 []
实际上等于 False
是没有意义的,因为它们显然是不同的值:字符串和列表。如果它们都等于False
,则它们必须彼此相等*。它们只是“假”,这意味着当它们被转换为布尔值时,它们会显示为假。
(*在任何合理构造的语言中)
not
是一个返回布尔值的操作。它返回哪个布尔值取决于操作数是否为假。所以not x
不等于x==False
;相当于bool(x)==False
。
【讨论】:
咳 看看 php 的逻辑:[] == false; '' == false; [] != '';
是的……
因此我的笔记在 *
那么,您是说''
是False
是不明智的,但说0
是有意义的?我知道布尔逻辑都是关于 0 和 1 的,但是,我说 ''
是 False
和说 not ''
是 True 一样有意义。
Python 表达式 '' is False
的计算结果为 false,因为 is
仅在操作数是对同一对象的引用时才返回 True。 '' is True
也评估为假,原因完全相同。
@TonyPower 在 Python 中 bool
是 int
的子类。 list
或 str
并非如此。基本上False
和True
只是0
和1
的特殊实例。例如。 True + 2 == 3
,而 [] + 2
给出错误。如果它们相等,那么您需要能够对字符串、列表和整数执行其他类型的操作。【参考方案3】:
这样的比较不是“Pythonic”(即这不是有经验的 Python 程序员自然会做的)。 Pythonic 的方法是在布尔上下文中使用一个值,例如 if
语句,然后让解释器不可见地应用 bool
内置函数来确定 True
或 False
值。这就是为什么人们通常会编写诸如
if lst:
print(headers)
for item in lst:
print(item.format())
else:
print(no_data_message)
而不是使用常见但不那么 Pythonic 的if len(lst):
或者更笨拙但功能正确的if len(lst) > 0:
。
不幸的是,在某些方面,Python 的设计者决定True
和False
将是bool
类型的实例,而bool
将是int
的子类。因此,True
比较等于 1
,False
比较等于 0
。数值转换说明了浮点(以及,就此而言,复数)结果。
但是仅仅因为bool(x) == True
并不意味着x == True
,正如bool(x) == False
意味着x == False
一样。还有许多其他值评估为 false,最著名的是
None
空字符串
空容器(列表、元组、字典)
他们不可能彼此平等!
【讨论】:
有道理。谢谢。 这对我来说是这个问题中最有价值的回答,因为它实际上解释了 为什么__eq__
运算符的行为方式——因为 bool 是 int 的子类型。这就是我在 Python 语言设计中缺少的洞察力。【参考方案4】:
如果你想检查official explanation,只需像这样转换你的值:
print(bool(None) == False)
print(False == False)
print(bool(0) == False)
print(bool(0.0) == False)
print(bool(0j) == False)
print(bool('') == False)
print(bool(()) == False)
print(bool([]) == False)
print(bool() == False)
【讨论】:
【参考方案5】:因为int(False) == 0
和int(True) == 1
。这就是 Python 在尝试评估 0 == False
时所做的事情。
另一方面,bool('') == False
。 bool([])
和 bool()
也是如此。
x
的计算结果为True
并不一定意味着x == True
。
【讨论】:
如果你换东西呢?例如:False == 0
是在做False == bool(0)
吗?如果是这样,它应该对空字符串做同样的事情,而不是这样做。
"这就是 is
应该用于检查布尔值而不是 ==
" 的原因——我不明白这是怎么回事
测试x is True
和x is False
对于x
的大多数值来说都是False,所以你应该使用is
的建议是非常错误的。
另外,了解所使用的机制。解释器将bool
函数应用于值。 bool
返回 True
或 False
。以上是关于Python:将空字符串与 False 进行比较是 False,为啥?的主要内容,如果未能解决你的问题,请参考以下文章