在列表中查找非公共元素

tur*_*oup 26 python algorithm list set discrete-mathematics

我正在尝试编写一段可以自动计算表达式的代码.例如,如果我有两个列表[1,2,3,4]和[2,3,5],代码应该能够找到两个列表中的公共元素,[2,3],并结合使用其余的元素在一个新的列表中,[1,4,5].

从这篇文章:如何找到列表交集? 我看到可以找到共同的元素

set([1,2,3,4]&set([2,3,5]). 
Run Code Online (Sandbox Code Playgroud)

有一种简单的方法可以从每个列表中检索非公共元素,在我的例子中是[1,4]和[5]吗?

我可以继续做一个for循环:

lists = [[1,2,3,4],[2,3,5]]
conCommon = []
common = [2,3]
for elem in lists:
    for elem in eachList:
    if elem not in common:
        nonCommon += elem
Run Code Online (Sandbox Code Playgroud)

但这似乎是多余和低效的.Python是否提供了可以做到的任何方便的功能?提前致谢!!

Amb*_*ber 49

sets 使用对称差分运算符(也称为XOR运算符):

>>> set([1,2,3]) ^ set([3,4,5])
set([1, 2, 4, 5])
Run Code Online (Sandbox Code Playgroud)


sai*_*uri 12

您可以使用Intersection概念来处理这类问题.

b1 = [1,2,3,4,5,9,11,15]
b2 = [4,5,6,7,8]
set(b1).intersection(b2)
Out[22]: {4, 5}
Run Code Online (Sandbox Code Playgroud)

使用此代码的最佳方法是它对大数据也很快.当我使用这个逻辑时,我有b1和607139以及b2和296029元素我在2.9秒内获得了我的结果.

  • 这并没有回答原来的问题。要求则相反。 (3认同)

elP*_*tor 5

老问题,但看起来 python 有一个内置函数来提供你正在寻找的内容:.difference().

例子

list_one = [1,2,3,4]
list_two = [2,3,5]

one_not_two = set(list_one).difference(list_two)
# set([1, 4])

two_not_one = set(list_two).difference(list_one)
# set([5])
Run Code Online (Sandbox Code Playgroud)

这也可以写成:

one_not_two = set(list_one) - set(list_two)
Run Code Online (Sandbox Code Playgroud)

定时

我对两者都进行了一些计时测试,似乎.difference()略有优势,大约为 10 - 15%,但每种方法需要大约八分之一秒来过滤 1M 项(500 到 100,000 之间的随机整数),所以除非你对时间非常敏感,这可能无关紧要。

其他注意事项

看来 OP 正在寻找一种解决方案,该解决方案提供两个单独的列表(或集合)-第一个包含不在第二个列表中的项目,反之亦然。以前的大多数答案都返回一个包含所有项目的列表或集合。

还有一个问题是,第一个列表中可能重复的项目是应该计算多次还是只计算一次。

如果 OP 想要维护重复项,可以使用列表理解,例如:

one_not_two = [ x for x in list_one if x not in list_two ]
two_not_one = [ x for x in list_two if x not in list_one ]
Run Code Online (Sandbox Code Playgroud)

...这与原始问题中提出的解决方案大致相同,只是更简洁一些。此方法将维持从原始列表重复,但显着地(如多个数量级)较慢对于较大数据集。