# Subtracting one list from another in python where duplicate values may occur

Asked by At

I am looking to remove the contents of one array from another.

``````array_2 = ['one' , "two" , "one", "three", "four"]
array_1 = ['one', "two"]
``````

My first thought was to use list comprehensions

``````array_3 = [x for x in array_2 if x not in array_1]
``````

However this will remove the duplicate item result : `['three', 'four']`

I want to only remove `"one"` once from the array as I am looking for a list subtraction. So I want the result to be : `['one', 'three', 'four']`.

What is a good pythonic way to achieve this ?

## 5 Answers On Best Solutions

I am just going to collect the excellent solutions already given above.

If you care about maintaining the original order in which the elements in `array_2` were, then I think you have to use `remove`:

``````array_1 = ['one', 'two']
array_2 = ['one', 'two', 'one', 'three', 'four']
array_3 = list(array_2)
for x in array_1:
try:
array_3.remove(x)
except ValueError:
pass
print(array_3)
``````

If it does not matter what the final order of elements is, then using `Counter` is much more efficient as it only loops over both lists once:

``````from collections import Counter

array_1 = ['one', 'two']
array_2 = ['one', 'two', 'one', 'three', 'four']
array_3 = list((Counter(array_2) - Counter(array_1)).elements())
print(array_3)
`````` On

Try `Counter` from `collections`:

``````from collections import Counter

array_2 = ['one' , "two" , "one", "three", "four"]
array_1 = ['one', "two"]

list((Counter(array_2) - Counter(array_1)).elements())
``````

output

``````['one', 'three', 'four']
`````` On

You could use the `remove` method of list:

``````array_2 = ['one' , "two" , "one", "three", "four"]
array_1 = ['one', "two"]

# copy list
array_3 = array_2[:]

for element in array_1:
try:
array_3.remove(element)
except ValueError:
pass
print(array_3)
# ['one', 'three', 'four']
`````` On

The `Counter` object feels perfect for this.

``````In : from collections import Counter

In : array_2 = ['one' , "two" , "one", "three", "four"]

In : array_1 = ['one', "two"]

In : a2 = Counter(array_2)

In : a1 = Counter(array_1)

In : a2 - a1
Out: Counter({'one': 1, 'three': 1, 'four': 1})
``````

If you want a list, you can flatten the `Counter` using:

``````In : list((a2-a1).elements())
Out: ['one', 'three', 'four']
`````` On

Using the `map` function in combination with a `lambda` would solve your task:

``````map(lambda x: array_2.remove(x) if x in array_2 else None, array_1)
``````

This would change the `array_2` directly and the result would be:

``````print(array_2)
# ['one', 'three', 'four']
``````