Python 在列表中查找非公共元素

Python 在列表中查找非公共元素,python,algorithm,list,set,discrete-mathematics,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]). 有没有一种简单的方法可以从每个列表中检索非公共元素,在我的示例中是[1,4]和[5] 我可以继续做一个for循环: lists = [[1,2,3,4],[2,3,5]] conCom

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

从本帖: 我发现这些共同元素可以通过

set([1,2,3,4]&set([2,3,5]). 
有没有一种简单的方法可以从每个列表中检索非公共元素,在我的示例中是[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

但这似乎是多余和低效的。Python是否提供了任何方便的函数来实现这一点?提前谢谢

set
s使用对称差分运算符(也称为异或运算符):


您可以使用交集概念来处理此类问题

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

使用这段代码最好的地方是,它对大数据的处理速度也相当快。我有b1和607139,b2和296029个元素,当我使用这个逻辑时,我在2.9秒内得到结果

您可以使用
属性方法

set([1,2,3,4]).__xor__(set([2,3,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])
这也可以写成:

one_not_two = set(list_one) - set(list_two)
定时

我对这两种方法都进行了一些计时测试,似乎
.difference()
有一点优势,大约为10-15%,但每种方法都需要大约八分之一秒的时间来过滤一百万个项目(500到100000之间的随机整数),因此除非你对时间非常敏感,否则这可能无关紧要

其他注释

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 ]

…这与原始问题中提出的解决方案大致相同,只是稍微干净一点。此方法将保留原始列表中的重复项,但对于较大的数据集,速度要慢得多(如多个数量级)。

这将获得公共元素和剩余元素

lis1=[1,2,3,4,5,6,2,3,1]
lis2=[4,5,8,7,10,6,9,8]

common = list(dict.fromkeys([l1 for l1 in lis1 if l1 in lis2]))
remaining = list(filter(lambda i: i not in common, lis1+lis2))
common=[4,5,6]


剩余=[1,2,3,2,3,1,8,7,10,9,8]

您可以使用对称差分命令

x={1,2,3} y={2,3,4}

z=设定差(x,y)


输出将是:z={1,4}

噢,哇,谢谢!!Bue上述代码是否与set([1,2,3])和set([3,4,5])的计算时间和内存空间相等?或者它对代码性能没有显著影响?它是实现目标的最有效的方法。它的复杂性与
的顺序相同(即,集合中元素的数量是线性的)。您希望得到单独的列表,如[1,4]和[5],还是一个单独的列表[1,4,5]?这并不能回答最初的问题。问题恰恰相反。
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 ]
lis1=[1,2,3,4,5,6,2,3,1]
lis2=[4,5,8,7,10,6,9,8]

common = list(dict.fromkeys([l1 for l1 in lis1 if l1 in lis2]))
remaining = list(filter(lambda i: i not in common, lis1+lis2))