Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 判断两个列表是否互为补充的最快方法?_Python_Python 3.x_List_Xor - Fatal编程技术网

Python 判断两个列表是否互为补充的最快方法?

Python 判断两个列表是否互为补充的最快方法?,python,python-3.x,list,xor,Python,Python 3.x,List,Xor,我有两个阵列: a = [0,1,0,1,0,1,0,1] b = [1,0,1,0,1,0,1,0] 确定每个元素是否是另一个元素(补码)的倒数的最快方法是什么 因此,为了让这一点变得明显,上述情况将变为现实 但对于这些阵列: a = [1,1,0,1,0,1,0,1] b = [1,0,1,0,1,0,1,0] 它将返回False 我认为这个问题很清楚,但要了解更多细节: 我所说的最快是指以秒为单位的最快速度 数组的长度不限于8个,但数组中的元素数将是相同的 元素将始终为0或1 我希望有

我有两个阵列:

a = [0,1,0,1,0,1,0,1]
b = [1,0,1,0,1,0,1,0]
确定每个元素是否是另一个元素(补码)的倒数的最快方法是什么

因此,为了让这一点变得明显,上述情况将变为现实

但对于这些阵列:

a = [1,1,0,1,0,1,0,1]
b = [1,0,1,0,1,0,1,0]
它将返回False

我认为这个问题很清楚,但要了解更多细节:

我所说的最快是指以秒为单位的最快速度

数组的长度不限于8个,但数组中的元素数将是相同的

元素将始终为0或1

我希望有偶数个非补码数组和补码数组


您可以压缩列表以比较对。为了知道它们是否相互“互补”,因为所有值都是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 va, vb in zip(a, b) if va + vb != 1)
速度又快了,大约10%。这对我来说毫无意义,因为加法运算比按位异或运算复杂得多

原始答案

您可以使用位异或来确定这些值是否为补码

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
可以使用执行按位异或以及将两个列表压缩在一起,并检查所有对是否都是补码或返回1:


数组值是一还是零?最快的是什么?固定尺寸?一些n?你的数据有什么限制吗?它们总是以列表形式开始,还是可以以不同的方式读取,比如整数或字节?你主要期望补语还是非补语序列?@Mistermiagi我相信我更新了这个问题来回答你的问题。我在这里看到你发布了一些其他方法不理想的原因-你对解决方案有什么建议吗?请注意,这不是最快的。它将在每个True上从生成器到all执行许多不必要的上下文切换。这肯定不是最快的。它将在每个迭代步骤上查找operator.xor。请注意,这不是最快的。它将在每个True上执行许多不必要的上下文切换,从生成器切换到all。@RoadRunner,因为我认为在这种状态下不应该回答这个问题。不管是哪种方式,如果不是a,b中a的形式alla的表达式通常比b中a的形式allFalse慢。@MisterMiyagi我很想知道这是为什么?现在你肯定会用更快的解决方案把你的同事搞糊涂了。20%的收益在我看来并不值得。@RoadRunner我只是想看看它是否真的更快,我想分享一下结果。
def is_complement(a, b):
    for i in range(len(a)):
        if a[i] == b[i]:
            return False
    return True
>>> 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