为啥空列表在 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__
)计算信息来定义的事实。不过,几乎没有这样的特殊情况(我认为<=
比较运算符有时会使用not >
之类的东西,如果它们没有明确定义的话,但我不记得了)。
为了向后兼容,真实性协议必须不断考虑一个类使用__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 循环中对列表框的更新最终导致我的程序挂起?
为啥我的 while 循环中的条件在 python 中不起作用?