Reputation: 763
I have two sorted lists of positive integers which can have repeated elements and I must remove matching pairs of numbers, one from each list:
a=[1,2,2,2,3]
b=[2,3,4,5,5]
should become:
a=[1,2,2]
b=[4,5,5]
That is, the 2's and the 3's have been removed because they appear in both lists.
Set intersection can't be used here because of the repeated elements.
How do I go about this?
Upvotes: 5
Views: 8718
Reputation:
To remove elements appearing in both lists, use the following:
for i in a[:]:
if i in b:
a.remove(i)
b.remove(i)
To create a function which does it for you, simply do:
def removeCommonElements(a, b):
for e in a[:]:
if e in b:
a.remove(e)
b.remove(e)
Or to return new lists and not to edit the old ones:
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
However the former could be replaced with removeCommonElements
like so:
a2, b2 = a.copy(), b.copy()
removeCommonElements(a2, b2)
Which would keep a and b, but create a duplicates without common elements.
Upvotes: 4
Reputation: 9584
The solution given by @Mahi is nearly correct. The simplest way to achieve what you want is this:
def remove_common_elements(a, b):
for i in a[:]:
if i in b:
a.remove(i)
b.remove(i)
return a, b
The important thing here is to make a copy of a
by writing a[:]
. If you iterate through a list while removing elements from it, you won't get correct results.
If you don't want to modify the lists in place, make a copy of both lists beforehand and return the copied lists.
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
Upvotes: 1
Reputation: 709
One solution would be to create a new copy of a and removing common elements from 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
Upvotes: 0
Reputation: 215039
Given that the lists are sorted, you can merge/distribute element-wise, like for example:
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
Upvotes: 2
Reputation: 33509
The Counter object from collections can do this quite concisely:
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())
The idea is:
(Warning: the output lists won't necessarily be sorted)
Upvotes: 2