I\'m aware variations of this question have been asked already, but none of the ones I\'ve been able to find have addressed my specific aim.
I am trying to take two
Essentially, you want a difference operation on a multi-set, i.e. a bag. Python implements this for the collections.Counter object:
Several mathematical operations are provided for combining Counter objects to produce multisets (counters that have counts greater than zero). Addition and subtraction combine counters by adding or subtracting the counts of corresponding elements. Intersection and union return the minimum and maximum of corresponding counts. Each operation can accept inputs with signed counts, but the output will exclude results with counts of zero or less.
So, for example:
>>> list1 = ["25","+","7","*","6","/","7"]
>>> list2 = ["7","*","6"]
>>> list((Counter(list1) - Counter(list2)).elements())
['25', '+', '7', '/']
In Python 3.6+ this will be ordered (although this is not currently guaranteed, and should probably be considered an implementation detail). If order is important, and you are not using this version, you may have to implement an ordered counter.
Indeed, the docs themselves provide just such a recipe:
>>> from collections import Counter, OrderedDict
>>> class OrderedCounter(Counter, OrderedDict):
... 'Counter that remembers the order elements are first encountered'
... def __repr__(self):
... return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))
... def __reduce__(self):
... return self.__class__, (OrderedDict(self),)
...
>>> list((OrderedCounter(list1) - OrderedCounter(list2)).elements())
['25', '+', '/', '7']
Using remove
method. Probably slow. O(n^2) in worse case.
list.remove(x)
Remove the first item from the list whose value is x. It is an error if there is no such item.
for i in list2:
list1.remove(i)
# list1 becomes
['25', '+', '/', '7']