比较两个数组并获得不常见的值

时间:2018-08-31 09:34:33

标签: python-3.x list duplicates copy

我正在做这个问题,一个朋友给我,在这里给你2个数组(a [1,2,3,4]和b [8,7,9,2,1]),您必须找到一个共同的要素。 预期输出为[3,4,8,7,9]。下面的代码。

def disjoint(e,f):
c = e[:]
d = f[:]
for i in range(len(e)):
    for j in range(len(f)):
        if e[i] == f[j]:
            c.remove(e[i])
            d.remove(d[j])
final = c + d
print(final)

print(disjoint(a,b))

我尝试使用嵌套循环并创建给定数组的副本以修改它们,然后添加它们,但是...

def disjoint(e,f):
c = e[:]                      # list copies
d = f[:]
for i in range(len(e)):
    for j in range(len(f)):
        if e[i] == f[j]:
            c.remove(c[i])     # edited this line
            d.remove(d[j])
final = c + d
print(final)

print(disjoint(a,b))

当我尝试从列表副本中删除公共元素时,会得到不同的输出[2,4,8,7,9]。为什么?? 这是我在本网站上提出的第一个问题。如果有人能消除我的疑虑,我将不胜感激。

2 个答案:

答案 0 :(得分:1)

您可以使用sets

a = [1,2,3,4]
b = [8,7,9,2,1]
diff = (set(a) | set(b)) - (set(a) & set(b))

(set(a) | set(b))是联合,set(a) & set(b)是交集,最后,您使用-进行两组运算之间的区别。

当您删除c.remove(c[i])d.remove(d[j])行中的元素时,您的错误就会出现。实际上,常见元素是e[i]f[j],而cd是您要更新的列表。
要修复您的错误,您只需将这些行更改为c.remove(e[i])d.remove(f[j])

请注意,如果列表中可能包含重复项,则您删除两个列表中项目的方法将不起作用。 例如,考虑a = [1,1,2,3,4]b = [8,7,9,2,1]的情况。

答案 1 :(得分:0)

您可以简化代码以使其起作用:

def disjoint(e,f):
    c = e.copy() # [:] works also, but I think this is clearer
    d = f.copy()
    for i in e: # no need for index. just walk each items in the array
        for j in f:
            if i == j: # if there is a match, remove the match.
                c.remove(i)
                d.remove(j)
    return c + d

print(disjoint([1,2,3,4],[8,7,9,2,1]))

Try it online!

有很多更有效的方法可以实现这一目标。检查以下堆栈溢出问题以发现它们:Get difference between two lists。我最喜欢的方法是使用set(就像@newbie的答案一样)。什么是set?让我们检查documentation

  

集合对象是不同的可哈希对象的无序集合。常见用途包括成员资格测试,从序列中删除重复项,以及计算数学运算,例如交集,并集,差和对称差。 (有关其他容器,请参见内置的dict,list和tuple类以及collections模块。)

强调我的

对称差异非常适合我们的需求!

  

返回一个在集合或指定的可迭代元素中都包含但不能同时包含两个元素的新集合。

确定如何在您的情况下使用它:

def disjoint(e,f):
    return list(set(e).symmetric_difference(set(f)))

print(disjoint([1,2,3,4],[8,7,9,2,1]))

Try it online!