2

I have two dictionaries of the following structure:

a) dict1 = {'a':[ [1,2], [3,4] ], 'b':[ [1,2],[5,6] ]}
b) dict2 = {'a':[ [1,2], [5,6] ], 'b':[ [1,2],[7,8] ]}

I need to find the set difference between each key in the dictionary i.e., dict1['a'] - dict2['a'] should return [3,4]. Any thought is appreciated.

2
  • What should happen for dict1 = {'c': [[1, 2], [3, 4]]}; dict2 = {'c':[[5, 6], [7, 8]]} ?
    – ilya n.
    Commented Aug 31, 2009 at 18:06
  • It should return dict1['c'] = [ [1,2], [3,4] ]
    – Prabhu
    Commented Sep 1, 2009 at 4:00

4 Answers 4

6

The use of mutable items (such as lists) makes the problem MUCH harder, as it precludes the simple use of Python's set data structure. It may be worth making temporary copies/versions which actually use tuples in lieu of those pesky lists:

def tempaux(d):
  return dict((k, set(tuple(x) for x in v))
              for k, v in d.iteritems())

Now:

def thedifs(dd1, dd2)
  d1 = tempaux(dd1)
  d2 = tempaux(dd2)
  allkeys = set(d1).update(d2)
  empty = set()
  difs = []
  for k in allkeys:
    s1 = d1.get(k, empty)
    s2 = d2.get(k, empty)
    adif = s1 - s2
    if adif: difs.append(adif)
  return difs

This assumes actual set difference rather than symmetric difference etc. You can of course turn back the tuples into lists before returns, &c, depending on your exact requirements.

3
>>> s1 = set([(1,2), (3,4)])
>>> s2 = set([(1,2), (5,6)])
>>> s1 - s2
{(3, 4)}
2

You've got the wrong data structure for what you're trying to do.

Use this instead.

dict1 = {'a': [(1, 2), (3, 4)], 'b': [(1, 2), (5, 6)]}
dict2 = {'a': [(1, 2), (5, 6)], 'b': [(1, 2), (7, 8)]}

Life is simpler when you try to do set operations on immutable objects like tuples.

This will transform your list-of-lists into a list-of-tuples.

>>> dict( (key,[tuple(v) for v in dict1[key]]) for key in dict1 )
{'a': [(1, 2), (3, 4)], 'b': [(1, 2), (5, 6)]}

Here's the complete solution.

>>> dict1t= dict( (key,[tuple(v) for v in dict1[key]]) for key in dict1 )
>>> dict2t= dict( (key,[tuple(v) for v in dict2[key]]) for key in dict2 )
>>> set(dict1t['a'])-set(dict2t['a'])
set([(3, 4)])
0
2

applicable to list or dict or number when a and b share the same structure

c={'a':'1','b':'2'}
d={'a':'10','b':'20'}
e={'x':c,'t':15}
f={'x':d,'t':19}

def diff(a,b):
    if isinstance(a, int) and isinstance(b, int):
        b = b - a
        return b
    if isinstance(a, str) and isinstance(b, str):
        if a.isdigit() and b.isdigit():
            b = str(int(b) - int(a))
            return b
        else:
            b = a
            return b
    if type(a) is list and type(b) is list:
        for i in range(len(a)):
            b[i] = diff(a[i],b[i])
        return b
    if type(a) is dict and type(b) is dict:
        for k,v in b.iteritems():
            b[k] = diff(a[k],b[k])
        return b

print diff(e,f)

Not the answer you're looking for? Browse other questions tagged or ask your own question.