Python中对两个列表进行 XOR 操作

25 投票
2 回答
56500 浏览
提问于 2025-04-18 00:29

我刚开始学习Python,现在需要对两个列表进行异或运算(第一个列表有600个元素,第二个有60个元素)。

我真的不知道该怎么做,如果有人能教我一下,我会非常感激。

我需要这样做是为了找到BPSK信号的模块,我在想怎么处理这两个长度不一样的列表。我看到过这个帖子:比较两个列表并只打印差异?(异或两个列表),但那个帖子里的列表长度是一样的。

谢谢你的帮助,抱歉我的英语不好。

2 个回答

20

这里有一个叫做 XOR 的操作符,用于集合。如果你确保集合里没有重复的元素(而且你也不在乎第二个列表里某个元素出现了几次),那么你可以在集合上使用 ^ 操作符:

>>> set([1, 2, 3, 4, 5]) ^ set([1, 3, 4, 5, 6])
set([2, 6])
>>> set(range(80)) ^ set(range(60))
set([60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79])
50

给定两个序列 seq1seq2,你可以用以下方法计算它们的 对称差集

set(seq1).symmetric_difference(seq2)

举个例子:

In [19]: set([1,2,5]).symmetric_difference([1,2,9,4,8,9])
Out[19]: {4, 5, 8, 9}

小贴士:用较小的列表生成集合通常会更快:

In [29]: %timeit set(range(60)).symmetric_difference(range(600))
10000 loops, best of 3: 25.7 µs per loop

In [30]: %timeit set(range(600)).symmetric_difference(range(60))
10000 loops, best of 3: 41.5 µs per loop

你可能会想用 symmetric difference 方法而不是 ^(尽管 ^ 的语法看起来很美),原因是 symmetric difference 方法可以接受列表作为输入。而 ^ 需要两个输入都是集合。把两个列表都转换成集合的计算量会比必要的多一些。


这个问题被标记为与 这个问题重复。不过,那个问题是在寻找不使用集合的解决方案。

被接受的解决方案:

[a for a in list1+list2 if (a not in list1) or (a not in list2)]

如果允许使用集合,这种方法并不是异或两个列表的推荐方式。首先,它的速度慢了超过100倍:

In [93]: list1, list2 = range(600), range(60)

In [94]: %timeit [a for a in list1+list2 if (a not in list1) or (a not in list2)]
100 loops, best of 3: 3.35 ms per loop

撰写回答