I am trying to create a new dict using a list of values of an existing dict as individual keys.

So for example:

dict1 = dict({'a':[1,2,3], 'b':[1,2,3,4], 'c':[1,2]})

and I would like to obtain:

dict2 = dict({1:['a','b','c'], 2:['a','b','c'], 3:['a','b'], 4:['b']})

So far, I've not been able to do this in a very clean way. Any suggestions?

  • 3
    out of curiosity: why do you need that? – Sven Hecht Sep 11 '09 at 10:31
  • This needs to be accessible in both directions as it'll happen a lot, and it needs to be serialisable, ideally without introducing more classes that would need importing if it was used in a separate module due to a complexity of the way the particular system i'm working with does things. – Dan Sep 11 '09 at 10:59

If you are using Python 2.5 or above, use the defaultdict class from the collections module; a defaultdict automatically creates values on the first access to a missing key, so you can use that here to create the lists for dict2, like this:

from collections import defaultdict
dict2 = defaultdict(list)
for key, values in dict1.items():
    for value in values:
        # The list for dict2[value] is created automatically

Note that the lists in dict2 will not be in any particular order, as a dictionaries do not order their key-value pairs.

If you want an ordinary dict out at the end that will raise a KeyError for missing keys, just use dict2 = dict(dict2) after the above.

  • You don't need a defaultdict for that simple thing. Just replace the append line to: dict2.setdefault(value, []).append(key) – nosklo Sep 11 '09 at 11:37
  • 2
    You don't ever "need" a default dict. It just makes code simpler. – Alice Purcell Sep 11 '09 at 11:39

Notice that you don't need the dict in your examples: the {} syntax gives you a dict:


Other way:

[[ (dict2.setdefault(i,[]) or 1) and (dict2[i].append(x)) for i in y ] for (x,y) in dict1.items()]  
  • 10
    -1 for a hideous abuse of Python: (1) List comprehensions should not have side-effects (2) Tortured boolean logic to achieve "a then b" – Alice Purcell Sep 11 '09 at 10:49
  • I really wish I could downvote this twice, just to make the point. Please put it out of its misery. – Alice Purcell Nov 15 '09 at 22:50

Your Answer

