Get the difference between 3 lists

I am working on list differences.

>>a = [1, 2, 3]
>>b = [2, 4, 5]
>>c = [3, 2, 6]

      

A symmetrical difference between the two sets can be accomplished with:

>>z = set(a).symmetric_difference(set(b))
>>print z
>>set([1, 3, 4, 5])

      

How to get the difference between 3 sets? For a difference of 3 sets, the expected output is:

expected output : set([1, 3, 4, 5, 6])

      

+3


source to share


4 answers


Just subtract the intersection from the union:

In [1]: a = set([1, 2, 3])

In [2]: b = set([2, 4, 5])

In [3]: c = set([3, 2, 6])

In [4]: (a | b | c) - (a & b & c)
Out[4]: set([1, 3, 4, 5, 6])

      

Or, to generalize to an arbitrary set of sets:

In [10]: l = [a, b, c]

In [11]: reduce(set.union, l) - reduce(set.intersection, l)
Out[11]: set([1, 3, 4, 5, 6])

      



or

In [13]: set.union(*l) - set.intersection(*l)
Out[13]: set([1, 3, 4, 5, 6])

      

(The latter is probably preferable.)

+9


source


How about this:



>>> a = [1, 2, 3]
>>> b = [2, 4, 5]
>>> c = [3, 2, 6]
>>> z1 = set(a).symmetric_difference(set(b))
>>> z2 = set(b).symmetric_difference(set(c))
>>> print z1.union(z2)
set([1, 3, 4, 5, 6])

      

+3


source


How about this:

def difflists(*lists):
    sets = map(set, lists)
    return set.union(*sets) - set.intersection(*sets)

print difflists(a, b, c)    # set([1, 3, 4, 5, 6])

      

If you want to exclude items that appear more than once:

from itertools import chain
from collections import Counter

def difflists(*lists):
    items = Counter(it for lst in lists for it in lst)
    return [it for it, count in items.iteritems() if count == 1]

print difflists(a, b, c)    # [1, 4, 5, 6]

      

These methods accept any number of lists

+3


source


@ NPE's answer doesn't work as expected as it relies on the result of outgoing operations. In your example, you can see an overlap of "3" from the first to the third, but still be included in the result.

>>> a = set(('a','b','c')) 
>>> b = set(('c','d','e'))
>>> c = set(('e','f','g'))
>>> (a | b | c) - (a & b & c)
set(['a', 'c', 'b', 'e', 'd', 'g', 'f'])

      

This is because it intersects 'a' at 'b' and then intersects 'c'. To fix this, you can:

>>> (a | b | c) - ((a & b) | (a & c) | (b & c))
set(['a', 'b', 'd', 'g', 'f'])

      

Also, to keep the two operations, you can get the symmetrical difference in two, combine with the third, then make the difference in combining the intersections of the first and third, second and third.

>>> ((a ^ b) | c) - ((a & c) | (b & c))
set(['a', 'b', 'd', 'g', 'f'])

      

0


source







All Articles