判断两个列表是否互为补充的最快方法?
Quickest way to tell if two lists are complements of each other?
我有两个数组:
a = [0,1,0,1,0,1,0,1]
b = [1,0,1,0,1,0,1,0]
确定每个元素是否为另一个元素(补码)的倒数的最快方法是什么?
所以为了使上面的内容显而易见 return True
但对于这些数组:
a = [1,1,0,1,0,1,0,1]
b = [1,0,1,0,1,0,1,0]
会returnFalse
我觉得这个问题已经很清楚了,但是要更详细一点:
"fastest" 我的意思是速度最快(以秒为单位)
数组的长度不限于8个,但数组中的元素个数相同
元素将始终是 0
或 1
我希望偶数个非补数组和补数组
您可以压缩列表以比较这些对。为了知道它们是否 'complement' 彼此,因为您的所有值都是 1 或 0,只需检查它们的总和是否为 1:
a = [0,1,0,1,0,1,0,1]
b = [1,0,1,0,1,0,1,0]
all(va + vb == 1 for va, vb in zip(a, b))
# True
a = [1,1,0,1,0,1,0,1]
b = [1,0,1,0,1,0,1,0]
all(va + vb == 1 for va, vb in zip(a, b))
# False
请注意,将 all
与生成器表达式一起使用只会检查需要决定的内容,一旦遇到无效的对,它将立即停止。
更新 2
如果数字只有1或0,您可以通过简单比较来测试补码。这比测试总和快了大约 15%:
complement = all(False for aa , bb in zip(a, b) if aa == bb)
更新
根据评论,我做了一些时间测试。在使用 all
即
测试列表之前过滤列表确实更快(大约 20%)
complement = all(False for aa, bb in zip(a, b) if aa ^ bb != 1)
奇怪的是:
complement = all(False for va, vb in zip(a, b) if va + vb != 1)
又快了大约 10%。这对我来说没有任何意义,因为加法是比按位异或复杂得多的操作。
原回答
您可以使用按位 xor
来确定值是否互补。
a = [0,1,0,1,0,1,0,1]
b = [1,0,1,0,1,0,1,0]
complement = all(aa ^ bb == 1 for aa , bb in zip(a, b))
print(complement)
# True
a = [1,1,0,1,0,1,0,1]
b = [1,0,1,0,1,0,1,0]
complement = all(aa ^ bb == 1 for aa , bb in zip(a, b))
print(complement)
# False
如果它们是 0
或 1
以外的值,这也可以通过与 2^n-1
比较来实现,其中 n
是值:
a = [3, 2, 1, 0]
b = [0, 1, 2, 3]
complement = all(aa ^ bb == 3 for aa , bb in zip(a, b))
print(complement)
# True
你可以用一个简单的 for 循环来做到这一点:
def is_complement(a, b):
for i in range(len(a)):
if a[i] == b[i]:
return False
return True
可以使用operator.xor
to do bitwise XOR along with zip
to zip the two lists together and all
来检查是否所有的对都是互补的或者return 1
:
>>> import operator
>>> a = [0,1,0,1,0,1,0,1]
>>> b = [1,0,1,0,1,0,1,0]
>>> all(operator.xor(x, y) for x, y in zip(a, b))
True
>>> a = [1,1,0,1,0,1,0,1]
>>> b = [1,0,1,0,1,0,1,0]
>>> all(operator.xor(x, y) for x, y in zip(a, b))
False
我有两个数组:
a = [0,1,0,1,0,1,0,1]
b = [1,0,1,0,1,0,1,0]
确定每个元素是否为另一个元素(补码)的倒数的最快方法是什么?
所以为了使上面的内容显而易见 return True
但对于这些数组:
a = [1,1,0,1,0,1,0,1]
b = [1,0,1,0,1,0,1,0]
会returnFalse
我觉得这个问题已经很清楚了,但是要更详细一点:
"fastest" 我的意思是速度最快(以秒为单位)
数组的长度不限于8个,但数组中的元素个数相同
元素将始终是
0
或1
我希望偶数个非补数组和补数组
您可以压缩列表以比较这些对。为了知道它们是否 'complement' 彼此,因为您的所有值都是 1 或 0,只需检查它们的总和是否为 1:
a = [0,1,0,1,0,1,0,1]
b = [1,0,1,0,1,0,1,0]
all(va + vb == 1 for va, vb in zip(a, b))
# True
a = [1,1,0,1,0,1,0,1]
b = [1,0,1,0,1,0,1,0]
all(va + vb == 1 for va, vb in zip(a, b))
# False
请注意,将 all
与生成器表达式一起使用只会检查需要决定的内容,一旦遇到无效的对,它将立即停止。
更新 2
如果数字只有1或0,您可以通过简单比较来测试补码。这比测试总和快了大约 15%:
complement = all(False for aa , bb in zip(a, b) if aa == bb)
更新
根据评论,我做了一些时间测试。在使用 all
即
complement = all(False for aa, bb in zip(a, b) if aa ^ bb != 1)
奇怪的是:
complement = all(False for va, vb in zip(a, b) if va + vb != 1)
又快了大约 10%。这对我来说没有任何意义,因为加法是比按位异或复杂得多的操作。
原回答
您可以使用按位 xor
来确定值是否互补。
a = [0,1,0,1,0,1,0,1]
b = [1,0,1,0,1,0,1,0]
complement = all(aa ^ bb == 1 for aa , bb in zip(a, b))
print(complement)
# True
a = [1,1,0,1,0,1,0,1]
b = [1,0,1,0,1,0,1,0]
complement = all(aa ^ bb == 1 for aa , bb in zip(a, b))
print(complement)
# False
如果它们是 0
或 1
以外的值,这也可以通过与 2^n-1
比较来实现,其中 n
是值:
a = [3, 2, 1, 0]
b = [0, 1, 2, 3]
complement = all(aa ^ bb == 3 for aa , bb in zip(a, b))
print(complement)
# True
你可以用一个简单的 for 循环来做到这一点:
def is_complement(a, b):
for i in range(len(a)):
if a[i] == b[i]:
return False
return True
可以使用operator.xor
to do bitwise XOR along with zip
to zip the two lists together and all
来检查是否所有的对都是互补的或者return 1
:
>>> import operator
>>> a = [0,1,0,1,0,1,0,1]
>>> b = [1,0,1,0,1,0,1,0]
>>> all(operator.xor(x, y) for x, y in zip(a, b))
True
>>> a = [1,1,0,1,0,1,0,1]
>>> b = [1,0,1,0,1,0,1,0]
>>> all(operator.xor(x, y) for x, y in zip(a, b))
False