两个布尔列表之间的逻辑运算

16

我在Python中尝试将andor操作符应用于两个布尔列表时,得到了奇怪的结果。实际上,我得到的结果与我的预期完全相反。

[True, False, False] and [True, True, False]
> [True, True, False]

[True, False, False] or [True, True, False]
> [True, False, False]

这正常吗?如果是的话,为什么?


2
你期望的是什么? - Josh Lee
1
我说的是"实际上我得到了完全相反于我期望的结果"。我本来期望第一个命令会导致第二个结果,而第二个命令会导致第一个结果。 - Yohan Obadia
7个回答

13

如果你实际想要的是两个列表之间的逐元素布尔运算,请考虑使用numpy模块:

>>> import numpy as np
>>> a = np.array([True, False, False])
>>> b = np.array([True, True, False])
>>> a & b
array([ True, False, False], dtype=bool)
>>> a | b
array([ True,  True, False], dtype=bool)

8
这很正常,因为andor实际上会将其操作数之一作为结果返回。x and y的作用类似于

def and(x, y):
    if x:
        return y
    return x

x或y类似时

def or(x, y):
    if x:
        return x
    return y

由于您两个列表都包含值,它们都是"真实值",因此and评估为第二个操作数,or评估为第一个。


1
你的回答是第一个正确的,谢谢。然而我发现 Davy 的更清晰,因此点赞但不是问题验证。谢谢! - Yohan Obadia

4
我认为你需要类似这样的东西:
[x and y for x, y in zip([True, False, False], [True, True, False])]

1
我不是在问如何做对,而是在问为什么会得到这个结果... - Yohan Obadia

3

这两个列表都是真值,因为它们是非空的。

andor 都返回决定了操作结果的值。

如果 and 左侧的值为真,那么它必须计算右侧的值,因为它可能是假的,这会导致整个操作变为假(假 and 任何东西都是假)。因此,它返回右侧的值。

如果 or 左侧的值为真,那么它不需要计算右侧的值,因为它已经知道表达式为真(真 or 任何东西都是真)。所以它返回左侧的值。

如果你想对列表中的项进行成对比较,请使用列表推导式,例如:

[x or y for (x, y) in zip(a, b)]     # a and b are your lists

2
你的列表并不是比较每个单独的值,而是比较列表中值的存在。
对于任何真实(truthy)的变量 a 和 b:
a and b
> b #The program evaluates a, a is truthy, it evaluates b, b is truthy, so it returns the last evaluated value, b.
a or b
> a #The program evaluates a, a is truthy, so the or statement is true, so it returns the last evaluated value, a.

现在,Truthy 取决于类型。例如,对于 my_int != 0,整数是 Truthy 的,而对于 my_int == 0,整数是 Falsy 的。因此,如果您有:

a = 0
b = 1
a or b
> b #The program evaluates a, a is falsy, so the or statement goes on to evaluate b, b is truthy, so the or statement is true and it returns the last evaluated value b.

2

更加功能强大:

from operator import or_, and_
from itertools import starmap

a = [True, False, False]
b = [True, True, False]
starmap(or_, zip(a,b))  # [True, True, False]
starmap(and_, zip(a,b))  # [True, False, False]

2
非常方便的方式:
>>> import numpy as np
>>> np.logical_and([True, False, False], [True, True, False])
array([ True, False, False], dtype=bool)
>>> np.logical_or([True, False, False], [True, True, False])
array([ True,  True, False], dtype=bool)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接