Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Remove a set of a list from another list

Tags:

python

list

set

array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
array2 = [1, 2, 2, 2, 5, 6, 6, 6, 9]

temp = set(array2)

array1.remove(temp)

Traceback (most recent call last):
  File "Sudoku V2.py", line 6, in <module>
    array1.remove(temp)
ValueError: list.remove(x): x not in list
like image 930
DGDD Avatar asked Sep 16 '13 02:09

DGDD


2 Answers

Try this:

array1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
array2 = [1, 2, 2, 2, 5, 6, 6, 6, 9]
set(array1).difference(array2)
=> set([3, 4, 7, 8])

The above makes use of the difference() method of sets, which returns a new set with elements in the set that are not in the iterable(s) received as parameter. Notice that there's no need to convert array2 to a set for this to work.

Also be aware that by using sets, all duplicate elements will be removed and the original order of the iterables won't necessarily be preserved. If that's an issue, try this alternative solution:

[x for x in array1 if x not in array2]
=> [3, 4, 7, 8]
like image 176
Óscar López Avatar answered Sep 20 '22 06:09

Óscar López


If you don't care about the order of elements in the result, or about duplicate elements, set.difference, as in Óscar López's answer, is exactly what you want.

If you do care about order and preserving duplicates, the simplest way is to just build a new list, filtering out the ones in array2:

set2 = set(array2)
array1 = [item for item in array1 if item not in set2]

If you need to destructively modify array1 in-place instead of building a new one, it's almost always simpler to just destructively replace the contents of array1 all at once:

array1[:] = [item for item in array1 if item not in set2]

If you really want to modify it element by element, the best way would be to iterate array1 backward, removing in-place:

set2 = set(array2)
for i, value in enumerate(array1)[::-1]:
    if value in set2:
        del array1[i]

Finally, you can do it the way flornquake suggested, but that will take quadratic time instead of linear, because it takes no advantage of the set; for each element in set2, it does a linear array1.remove.

like image 43
abarnert Avatar answered Sep 20 '22 06:09

abarnert