wich - 1 year ago 259
Python Question

# Subtracting two lists in Python

In Python, How can one subtract two non-unique, unordered lists? Say we have

`a = [0,1,2,1,0]`
and
`b = [0, 1, 1]`
I'd like to do something like
`c = a - b`
and have
`c`
be
`[2, 0]`
or
`[0, 2]`
order doesn't matter to me. This should throw an exception if a does not contain all elements in b.

Note this is different from sets! I'm not interested in finding the difference of the sets of elements in a and b, I'm interested in the difference between the actual collections of elements in a and b.

I can do this with a for loop, looking up the first element of b in a and then removing the element from b and from a, etc. But this doesn't appeal to me, it would be very inefficient (order of
`O(n^2)`
time) while it should be no problem to do this in
`O(n log n)`
time.

Python 2.7 and 3.2 will add the collections.Counter class which is a dictionary that maps elements to the number of occurrences of the element. This can be used as a multiset.

According to the docs you should be able to do something like this (untested, since I do not have either version installed).

``````from collections import Counter
a = Counter(0,1,2,1)
b = Counter(0,1,1)

print a - b  # ignores items in b missing in a

# check every element in a is in b
# a[key] returns 0 if key not in a, instead of raising an exception
assert all(a[key] > b[key] for key in b)
``````

Edit:

Since you are stuck with 2.5 you could try importing it and define your own version if that fails. That way you will be sure to get the latest version if it is available, and fall back to a working version if not. You will also benefit from speed improvements if if gets converted to a C implementation in the future.

i.e.

``````try:
from collections import Counter
except ImportError:
class Counter(dict):
...
``````

You can find the current Python source here.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download