在Python中不改变顺序地相减相加两个列表

2 投票
6 回答
1138 浏览
提问于 2025-04-16 22:36

假设我有一个列表 [68,31,93,35,10](这些数字都是不同的),还有一个列表 [93,0,22,10,99,33,21,9](这些数字也都是不同的,但可能和第一个列表有一些重复)。我想要得到一个新的列表 [68,31,93,35,10,0,22,99,33,21,9],这个列表是把第二个列表的内容加到第一个列表上,但不能有重复的数字。同时,我还想得到一个列表 [68,31,35],这个列表是把第一个列表中在第二个列表里出现的重复数字去掉后的结果。输出的顺序要和输入的一样。请问我该怎么做呢?(如果能用一行代码实现就更好了。)

6 个回答

0

在这样定义前两个列表之后,

a = [68,31,93,35,10]
b = [93,0,22,10,99,33,21,9]

这是第一个问题的一行解决方案,

c = [x for x in a+b if x not in set(a).intersection(set(b))]

这是第二个问题的一行解决方案,

d = [x for x in a+b if x not in b]
4
l1 = [68, 31, 93, 35,10]
l2 = [93, 0, 22, 10, 99, 33, 21,9]

l1 + [x for x in l2 if not x in l1]
# [68, 31, 93, 35, 10, 0, 22, 99, 33, 21, 9]

[x for x in l1 if not x in l2]
# [68, 31, 35]

编辑:对于很长的列表,你不想进行那么多的列表查找。这里有两个其他的方法:

合并:

from collections import OrderedDict
OrderedDict().fromkeys(l1+l2).keys()
# [68, 31, 93, 35, 10, 0, 22, 99, 33, 21, 9]

差异:

s = set(l2)
[x for x in l1 if not x in s]
# [68, 31, 35]
2

假设你有两个输入 l1l2,你可以用下面的方法来计算它们的有序合并:

l1 + filter(lambda x: x not in l1, l2)

如果你想得到有序的差集 l1 - l2,可以这样写:

filter(lambda x: x not in l2, l1)

另外,你也可以使用列表推导式来实现:

>>> l1 = [68,31,93,35,10]
>>> l2 = [93,0,22,10,99,33,21,9]
>>> l1 + [el2 for el2 in l2 if el2 not in l1]
[68, 31, 93, 35, 10, 0, 22, 99, 33, 21, 9]
>>> [el1 for el1 in l1 if el1 not in l2]
[68, 31, 35]

如果你处理的是非常大的列表(性能可能会成为问题),可以构建一个 set 来加快查找速度:

>>> sl1 = set(s1)
>>> l1 + [el2 for el2 in l2 if el2 not in sl1]
[68, 31, 93, 35, 10, 0, 22, 99, 33, 21, 9]
>>> sl2 = set(s2)
>>> [el1 for el1 in l1 if el1 not in sl2]
[68, 31, 35]

撰写回答