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

0
1313e 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)
2
sentence 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']
1
Community 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']
0
ZaydH On

The Counter object feels perfect for this.

In [1]: from collections import Counter                                                                                                                                      

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

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

In [4]: a2 = Counter(array_2)                                                                                                                                                

In [5]: a1 = Counter(array_1)                                                                                                                                                

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

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

In [7]: list((a2-a1).elements())                                                                                                                                             
Out[7]: ['one', 'three', 'four']
0
Manu mathew 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']