【发布时间】:2016-11-05 19:39:06
【问题描述】:
我在 Python 中发现了一些非常奇怪的行为。 我的一个学生在尝试查找属于两个列表的元素时犯了某种错误,他写道:
list1 and list2
奇怪的行为是 Python 3 没有触发错误!
list1 and list2 实际上有一个值是 list2。
这有什么已知的原因吗?
【问题讨论】:
标签: python python-3.x operators
我在 Python 中发现了一些非常奇怪的行为。 我的一个学生在尝试查找属于两个列表的元素时犯了某种错误,他写道:
list1 and list2
奇怪的行为是 Python 3 没有触发错误!
list1 and list2 实际上有一个值是 list2。
这有什么已知的原因吗?
【问题讨论】:
标签: python python-3.x operators
and 只是评估所提供的两个值的真实性。
如果第一个是True(参见bool(list1)),则计算并返回第二个。如果第一个参数是False(例如[] and list2),则立即返回其值。
在documentation on Boolean Operations 中明确说明了这种行为的基本原理:
请注意,
and和or都不会限制它们返回到False和True的值和类型,而是返回最后评估的参数。这有时很有用,例如,如果s是一个字符串,如果它是空的,则应该将其替换为默认值,则表达式s or 'foo'会产生所需的值。
(强调我的)
请注意,not 找不到此行为,而是根据提供的参数返回 True/False 值。
【讨论】:
好吧,如果它们都有值,那么“if list1 和 list2:”应该返回 True,它将继续到代码中的下一行。 如果变量与 None 或 0 不同,Python3 认为 True。 示例:
a = 1
if a: #This will be True since a is different then None or 0
print("Works")
>>> Works
b = 0
if b:
print("Works")
>>>
This one returned nothing because b is 0 wich means that the "if b" will return False.
此外,如果列表中至少有 1 个元素,它将在列表上返回 True。
【讨论】:
当您询问list1 and list2 时,python 会在list1 和list2 上调用__bool__。由于[] 的计算结果为False,并且非空列表的计算结果为True,and 依次查看list1 和list2,直到找到一个空列表(或查看所有列表,如果从未找到空列表)。
最后,and 表达式的计算结果要么是导致 and 失败的空列表,要么是比较中的最后一个列表。这就是为什么您会返回 list2 作为值。
有趣的是,您可以利用这种行为来设置默认值:
def func(arg=None):
arg = arg or [5] # now, [5] is the default value of arg
这实际上和做的一样:
def func(arg=None):
if arg is None:
arg = [5]
【讨论】: