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:FalseNone、所有类型的数字零以及空字符串和容器(包括字符串、元组、列表、字典、集合和冻结集)。所有其他值都被解释为 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__,一个对象与另一个对象的直接比较。因此,可以询问一个对象是否认为自己是 truthyfalsey,并与此分开询问它是否认为自己与另一个对象相等。其默认实现以这样一种方式排列,即两个对象都可以认为自己 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 中 boolint 的子类。 liststr 并非如此。基本上FalseTrue 只是01 的特殊实例。例如。 True + 2 == 3,而 [] + 2 给出错误。如果它们相等,那么您需要能够对字符串、列表和整数执行其他类型的操作。【参考方案3】:

这样的比较不是“Pythonic”(这不是有经验的 Python 程序员自然会做的)。 Pythonic 的方法是在布尔上下文中使用一个值,例如 if 语句,然后让解释器不可见地应用 bool 内置函数来确定 TrueFalse 值。这就是为什么人们通常会编写诸如

之类的代码
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 的设计者决定TrueFalse 将是bool 类型的实例,而bool 将是int 的子类。因此,True 比较等于 1False 比较等于 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) == 0int(True) == 1。这就是 Python 在尝试评估 0 == False 时所做的事情。

另一方面,bool('') == Falsebool([])bool() 也是如此。

x 的计算结果为True 并不一定意味着x == True

【讨论】:

如果你换东西呢?例如:False == 0 是在做False == bool(0) 吗?如果是这样,它应该对空字符串做同样的事情,而不是这样做。 "这就是 is 应该用于检查布尔值而不是 ==" 的原因——我不明白这是怎么回事 测试x is Truex is False 对于x 的大多数值来说都是False,所以你应该使用is 的建议是非常错误的。 另外,了解所使用的机制。解释器将bool 函数应用于值。 bool 返回 TrueFalse

以上是关于Python:将空字符串与 False 进行比较是 False,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 unicode 类型与 python 中的字符串进行比较?

将字符串与字符串列表进行比较以在 Python 中查找字谜

2021/5/24回文子串与中心扩展法动态规划法

如果将字符串与整数进行比较,它会评估为false吗?

将字符串与数据库中的字符串进行比较返回 false

json串与python类型(字典)的转换