python 中 "and" 运算符的问题

Problem with the "and" operator in python

我正在做一个看似简单的练习,但我 运行 遇到了“and”运算符的问题。 我想我很了解它是如何工作的:

print("0 and 0 : ", (0 and 0))
print("0 and 1 : ", (0 and 1))
print("1 and 0 : ", (1 and 0))
print("1 and 1 : ", (1 and 1))
print((0 and 1) == (1 and 0))

这给了我预期的结果:

0 and 0 :  0
0 and 1 :  0
1 and 0 :  0
1 and 1 :  1
True

但是当我 运行 这个代码时:

A = '00111000111000111000111000'
B = '00001110001110001110001110'

for i in range(len(A)):
    s1s2 = (A[i] and B[i])
    s2s1 = (B[i] and A[i])
    print(f"s1={A[i]}, s2={B[i]}, s1 and s2 = {s1s2} ; s2 and s1 = {s2s1} :", (s1s2) == (s2s1))

我在 VSCode 上使用 Python3.9 在我的控制台中得到了无意义的结果(我也在网上试过):

s1=1, s2=0, s1 and s2 = 0 ; s2 and s1 = 1 : False
s1=0, s2=1, s1 and s2 = 1 ; s2 and s1 = 0 : False

“或”也有同样的问题。

A = '00111000111000111000111000'
B = '00001110001110001110001110'
for i in range(len(A)):
    s1s2 = (A[i] or B[i])
    s2s1 = (B[i] or A[i])
    print(f"s1={A[i]}, s2={B[i]} || s1 or s2 = {s1s2} ; s2 or s1 = {s2s1}  || s1s2 == s2s1 : ", (s1s2) == (s2s1))

那个returns没意义的东西:

s1=1, s2=0 || s1 or s2 = 1 ; s2 or s1 = 0  || s1s2 == s2s1 :  False
s1=0, s2=1 || s1 or s2 = 0 ; s2 or s1 = 1  || s1s2 == s2s1 :  False

我试图在 运行 循环之前将字符串 A 和 B 转换成列表,但它给了我相同的结果。 你知道这里发生了什么吗?我遗漏了什么或做错了什么?

您正在对 non-empty 个字符串执行 AND 或 OR。那些总是评估为 True.

and returns 计算结果为 False 的第一个值或最后一个值,以防其中 none 为假。 Python 中字符串的布尔值对于每个 non-empty ("") 字符串都是 True。这意味着即使 '0' 被认为是 True 而 0 (整数)不是。

考虑到两者,当你逐个字符s1 and s2时,它的值将是s2,因为它是最后一个并且所有评估为True。

让我们来看一个稍微不同的案例:

0 and None -> 0
None and 0 -> None
'1' and '0' -> '0'
'0' and '1' -> '1'

为什么?那么在前两种情况下,0(一个整数)和 None 都是假的,所以第一个被返回。在后两种情况下,您有 non-empty 个字符串,它们都是真值,因此返回第二个。

有几种方法可以使第二个结果与整数比较相同。最简单的方法是将每个位按需转换为整数:

A = '00111000111000111000111000'
B = '00001110001110001110001110'
for a, b in zip(A, B):
    a = int(a)
    b = int(b)
    s1s2 = (a and b)
    s2s1 = (b and a)
    print(f"s1={a}, s2={b}, s1 and s2 = {s1s2} ; s2 and s1 = {s2s1} :", (s1s2) == (s2s1))

另一种方法是直接使用整数并使用 bit-twiddling。这需要您明确设置位数,因为 int(A).bit_length() 之类的东西会丢弃任何前导零:

N = 26
A = 0b00111000111000111000111000
B = 0b00001110001110001110001110
for i in range(N - 1, -1, -1):
    a = (A & (1 << i)) >> i
    b = (B & (1 << i)) >> i
    s1s2 = (a and b)
    s2s1 = (b and a)
    print(f"s1={a}, s2={b}, s1 and s2 = {s1s2} ; s2 and s1 = {s2s1} :", (s1s2) == (s2s1))

在这两种情况下都可以省略>> i,因为它不会影响(X & (1 << i))选择的位的真值。另外,1 << i == 2**i.