I have two lists, let’s say:
a = [1,2,3]
b = [1,2,3,1,2,3]
I would like to remove 1, 2 and 3 from list b, but not all occurrences. The resulting list should have:
b = [1,2,3]
I currently have:
for element in a:
try:
b.remove(element)
except ValueError:
pass
However, this has poor performance when a and b get very large. Is there a more efficient way of getting the same results?
EDIT
To clarify ‘not all occurrences’, I mean I do not wish to remove both ‘1’s from b, as there was only one ‘1’ in a.
I would do something like this:
Or, if you are willing to be slightly more obscure:
defaultdict generates a count of the occurrences of each key. Once it has been built up from
b, it is decremented for each occurrence of a key ina. Then we print out the elements that are still left over, allowing them to occur multiple times.defaultdict works with python 2.6 and up. If you are using a later python (2.7 and up, I believe), you can look into
collections.Counter.Later: you can also generalize this and create subtractions of counter-style defaultdicts:
But the
reduceexpression is pretty obscure now.Later still: in python 2.7 and later, using
collections.Counter, it looks like this: