为啥空列表在 Python 的 while 循环中计算为 False

Posted

技术标签:

【中文标题】为啥空列表在 Python 的 while 循环中计算为 False【英文标题】:Why does an empty list evaluates to False on a while loop in Python为什么空列表在 Python 的 while 循环中计算为 False 【发布时间】:2019-03-23 09:57:12 【问题描述】:

while 循环在空列表上评估为False 的过程是什么?

例如:

a=[1, 2, 3]
while a:
    a.pop()

本质上,我想知道while-loop 正在检查列表对象的哪个方法或属性,以决定是否终止。

【问题讨论】:

Empty list is equal to None or not?的可能重复 一个更好的可能副本是***.com/q/10440792/8344060 @kvantour。两者都不是一个好的副本 我同意@Mad Physicist 的观点。我认为这里的问题以及提供的解决方案更加清晰。 【参考方案1】:

循环和条件在其所有条件上都隐式使用bool。该过程在文档的"Truth Value Testing" 部分中明确记录。对于像列表这样的序列,这通常会检查__len__ 方法。

bool 的工作方式如下:首先它尝试__bool__ 方法。如果__bool__ 没有实现,它会检查__len__ 是否非零,如果不可能,则返回True

与所有魔术方法查找一样,Python 只会查看类,而不会查看实例(请参阅Special method lookup)。如果您的问题是关于如何改变行为,则需要子类化。将单个替换方法分配给实例字典根本不起作用。

【讨论】:

在 Python 3+ 中是这样吗?我试过a = []。然后 a.__bool__() 并返回此方法不存在。 @VanillaSpice。我已添加到我的答案中 其实我找到了这个链接:docs.python.org/3/library/stdtypes.html#truth,并将其添加到您的答案中以使其更完整。【参考方案2】:

好问题!它正在检查bool(a),它(通常)调用type(a).__bool__(a)

Python 使用“魔术方法”来实现某些东西。基本上,如果你有这样定义的数据类型:

class MyExampleDataType:
    def __init__(self, val):
        self.val = val

    def __bool__(self):
        return self.val > 20

然后这段代码会做它看起来会做的事情:

a = MyExampleDataType(5)
b = MyExampleDataType(30)

if a:
    print("Won't print; 5 < 20")
if b:
    print("Will print; 30 > 20")

有关详细信息,请参阅 Python 文档:3.3 Special Method Names。

【讨论】:

我试过 mylist=[]。然后 mylist.__bool__() 并返回此方法不存在。 __bool__ 方法是 list 的实际方法吗? @VanillaSpinIce 这很复杂。列表是一个不好的例子;实际上没有list.__bool__。阅读this 了解详细信息;基本上,Python 弥补了list.__bool__ 不是通过以另一种方式(即使用list.__len__)计算信息来定义的事实。不过,几乎没有这样的特殊情况(我认为&lt;= 比较运算符有时会使用not &gt; 之类的东西,如果它们没有明确定义的话,但我不记得了)。 为了向后兼容,真实性协议必须不断考虑一个类使用__len__,而不是新来者__bool__(或Python 2方法__nonzero__被它取代)的可能性,以定义其真实性。既然如此,就没有令人信服的理由为 Python 3 中的 list 等内置类型定义 __bool__ __len__【参考方案3】:

if my_var 这样的条件等价于if bool(my_var),this page 很好地解释了它:

bool() 的返回值

bool() 返回:

如果该值被省略或为假,则为假 如果值为真,则为真

以下值在 Python 中被认为是错误的:

错误

任何数字类型的零。例如,0、0.0、0j

空序列。例如,()、[]、''。

空映射。例如,

具有返回 0 或 False 的 bool() 或 len() 方法的类的对象

除了这些值之外的所有其他值都被认为是真的。

【讨论】:

【参考方案4】:

您可以使用 bool() 函数检查列表是否为空。如果变量不存在或在列表的情况下为空,则评估为 False。

在你的情况下,你可以这样做:

a=[1,2,3]

while bool(a) is True:
    a.pop()

或者更简单:

a = [1,2,3]

while len(a) > 0:

    print(a.pop())

【讨论】:

以上是关于为啥空列表在 Python 的 while 循环中计算为 False的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在使用 PySimpleGUI 的 while 循环中对列表框的更新最终导致我的程序挂起?

python 第三章 元祖,字典,集合,while循环

为啥我的 while 循环中的条件在 python 中不起作用?

Python while循环popleft() - 错误:空双端队列

空while循环的Python语法

Python基础之推导式