不明白为什么(5 | -2)> 0为False(5或-2)> 0为True

mad*_*aks 18 python conditional

这是一个非常琐碎的问题,我无法找到答案。

这是问题所在。我有以下数组:

vals = [-5, 2]
Run Code Online (Sandbox Code Playgroud)

我想检查是否val[0]val[1]大于0。如果任何一个是真的,那么我应该输出为True。

我立即想到使用。(vals[1] or vals[0]) > 0)但我发现那(5 | -2) > 0是False,哪里(5 or -2) > 0是True

任何澄清将不胜感激。

kal*_*ann 44

or和之间有什么区别|

or是逻辑或,并且|是按位或逻辑包含(或)。

逻辑或

逻辑或python中返回的第一个值为true。

例:

>>> None or False or 5
5
>>> -5 or 2
-5
Run Code Online (Sandbox Code Playgroud)

按位或逻辑包含性或

按位或逻辑包含或由|python中的运算符表示,并创建一个数字,其中设置了所有位数的位数至少在给定的数值中设置了一个

例:

  • 2是二进制 0010
  • 4是二进制 0100

逻辑结果或两者之间的结果0110为6。

>>> 2 | 4
6
Run Code Online (Sandbox Code Playgroud)

如何存储负数通常是特定于实现的。但是,在大多数系统上,通过反转每个位并加1 来创建正数的二进制补码来存储负数。

按位矿石或任意两个其他数字中的那个数字仍会导致一个负数:

>>> -5 | 2
-5
Run Code Online (Sandbox Code Playgroud)

两者都不能解决您的问题

使用时

(vals[1] or vals[0]) > 0
Run Code Online (Sandbox Code Playgroud)

似乎有效,但是当您翻转值时它会失败:

>>> vals = [2, -5]
>>> (vals[1] or vals[0]) > 0
False
Run Code Online (Sandbox Code Playgroud)

您应该分别检查两个值

>>> vals = [-5, 2]
>>> vals[0] > 0 or vals[1] > 0
True
Run Code Online (Sandbox Code Playgroud)

对于较大的输入,这可能不方便。您应该将任何与生成器表达式一起使用:

>>> any(x > 0 for x in vals)
True
Run Code Online (Sandbox Code Playgroud)


che*_*ner 14

您需要该any功能:

>>> any(x > 0 for x in vals)
Run Code Online (Sandbox Code Playgroud)

x | y计算OR两个值的按位计算,同时x or y求值第一个“真实”值。在两种情况下,都将结果0(x or y) > 0和进行比较(x | y) > 0

您想要将每个值都比较为零(根据需要)的结果

vals[0] > 0 or vals[1] > 0
Run Code Online (Sandbox Code Playgroud)

如果你有三个值,你会写

vals[0] > 0 or vals[1] > 0 or vals[2] > 0
Run Code Online (Sandbox Code Playgroud)

any函数将其通用化为任意大小的列表,而无需根据列表的大小决定将多少个词or合并在一起。


小智 5

要回答这个问题,我必须解释一下Two's Complement。

数字的二进制表示

因此,您知道内部如何将5等整数表示为二进制字符串

00000000000000000000000000000101
Run Code Online (Sandbox Code Playgroud)

您如何想象自己代表一个负数?

好吧,这是我们想要做的:

  • 负数和正数的加法应该相同;即,您执行相同的步骤将4 + 9添加为4 + -9。

  • 整数溢出不应破坏数学。也就是说MAX_VALUE + 1 == MIN_VALUEMIN_VALUE - 1 == MAX_VALUE

因此,我们做的就是“二进制补码”。

两个补全

要表示一个负数,请取其绝对值,对每一位进行位翻转,然后加1。

所以如果正数是5

00000000000000000000000000000101
Run Code Online (Sandbox Code Playgroud)

负数-5为

11111111111111111111111111111011
Run Code Online (Sandbox Code Playgroud)

从本质上讲,这意味着我们将数字选为01111111111111111111111111111111最大的正数,之后的所有数字均为负。

那么(5 | -2)意味着什么呢?

|是按位或操作。给定两个数字,它将每个位和(或)与它们在一起,从而构造一个新数字,如果该位置上的数字枯萎或两个原始数字都为1,则数字为1,否则为0。计算结果如下:

   5 -> 00000000000000000000000000000101
| -2 -> 11111111111111111111111111111110
----    --------------------------------
        11111111111111111111111111111111 -> -1
Run Code Online (Sandbox Code Playgroud)

如您所见,5 | -2 = -1 <0。

关于(5或-2)?

“或”运算符采用两个值,并将它们强制转换为布尔值和或的。这很重要:它不包含值或不包含值,它返回第一个“真实的”值-换句话说,如果将其放在if语句中,它将运行。

唯一不“真实”的整数是0。因此,(5或-2)将返回第一个非零整数5和2,即5>0。因此5或-2 = 5> 0。