5

我有两个可以包含重复元素的正整数排序列表,我必须删除匹配的数字对,每个列表中一个:

a=[1,2,2,2,3]
b=[2,3,4,5,5]

应该变成:

a=[1,2,2]
b=[4,5,5]

也就是说,2 和 3 已被删除,因为它们出现在两个列表中。

由于元素重复,此处不能使用集合交集。

我该怎么做?

4

5 回答 5

4

要删除出现在两个列表中的元素,请使用以下命令:

for i in a[:]:
    if i in b:
        a.remove(i)
        b.remove(i)

要创建一个为您执行此操作的函数,只需执行以下操作:

def removeCommonElements(a, b):
    for e in a[:]:
        if e in b:
            a.remove(e)
            b.remove(e)

或者返回新列表而不是编辑旧列表:

def getWithoutCommonElements(a, b): # Name subject to change
    a2 = a.copy()
    b2 = b.copy()
    for e in a:
        if e not in b:
            a2.remove(e)
            b2.remove(e)
    return a2, b2

但是前者可以替换为removeCommonElements

a2, b2 = a.copy(), b.copy()
removeCommonElements(a2, b2)

这将保留 a 和 b,但会创建一个没有共同元素的副本。

于 2013-01-11T10:21:18.893 回答
2

集合中的 Counter 对象可以非常简洁地做到这一点:

from collections import Counter
a=Counter([1,2,2,2,3])
b=Counter([2,3,4,5,5])
print list((a-b).elements())
print list((b-a).elements())

这个想法是:

  1. 计算每个元素出现的频率(例如 2 在 a 中出现 3 次,在 b 中出现 1 次)
  2. 减去计数以计算元素出现的额外次数(例如 2 在 a 中出现 3-1=2 倍于 b)
  3. 输出每个元素出现的额外次数(集合元素方法会自动删除任何计数小于 1 的元素)

(警告:输出列表不一定会排序)

于 2013-01-11T10:37:34.140 回答
2

鉴于列表已排序,您可以按元素合并/分布,例如:

x, y = [], []

while a and b:
    if a[0] < b[0]:
        x.append(a.pop(0))
    elif a[0] > b[0]:
        y.append(b.pop(0))
    else: # a[0]==b[0]
        a.pop(0)
        b.pop(0)

x += a
y += b
于 2013-01-11T10:44:57.550 回答
1

@Mahi 给出的解决方案几乎是正确的。实现您想要的最简单的方法是:

def remove_common_elements(a, b):
    for i in a[:]:
        if i in b:
            a.remove(i)
            b.remove(i)
     return a, b

这里重要的是a通过书写来复制a[:]。如果您在从列表中删除元素的同时遍历列表,您将不会得到正确的结果。

如果您不想就地修改列表,请事先复制两个列表并返回复制的列表。

def remove_common_elements(a, b):
    a_new = a[:]
    b_new = b[:]
    for i in a:
        if i in b_new:
            a_new.remove(i)
            b_new.remove(i)
    return a_new, b_new
于 2013-01-11T10:59:21.213 回答
0

一种解决方案是创建 a 的新副本并从 b 中删除公共元素。

a = [1,2,2,2,3]
b = [2,2,3,4,5]

a_new = []
for ai in a:
    if ai in b:
        b.remove(ai)
    else:
        a_new.append(ai)

print a_new
print b
于 2013-01-11T11:04:10.653 回答