1

Say I have a dictionary dict, with the following values:

dict1 = {'1': ['a','b', 'c', 'd'], '2': ['e','f', 'g', 'h']}

How would I make one of the values the key in a new dictionary, dict1?

dict2 = {'d': ['a','b', 'c', '1'], 'h': ['e','f', 'g', '2']}
user725236
  • 165
  • 2
  • 3
  • 9

3 Answers3

6
In [12]: d = {'1': ['a','b', 'c', 'd'], '2': ['e','f', 'g', 'h']}

In [13]: dict((v[-1],v[:-1]+[k]) for k,v in d.iteritems())
Out[13]: {'d': ['a', 'b', 'c', '1'], 'h': ['e', 'f', 'g', '2']}

k is the original key, v is the original value (the list). In the result, v[-1] becomes the new key and v[:-1]+[k] becomes the new value.

edit As pointed out by Adrien Plisson, Python 3 does not support iteritems. Also, in Python 2.7+ and 3, one can use a dictionary comprehension:

{v[-1]: v[:-1]+[k] for k,v in d.items()} # Python 2.7+
NPE
  • 486,780
  • 108
  • 951
  • 1,012
0

make the key a value, and a value the key:

dict2 = dict( (dict1[key], key) for key in dict1 )

or

dict2 = dict( (value,key) for key, value in dict1.items() )

Both work for all versions of Python.


special case

Only in the special case of the example in the question this does not work, because a list cannot be used as a key. So using the last element of each list as key and replacing this last element with the previous key, we get the more complicated:

dict2 = dict( (dict1[key][-1], dict1[key][:-1]+[key]) for key in dict1 )

Note that from Python 3.0, dict.iterkeys(), dict.itervalues(), and dict.iteritems() are no longer valid. dict.keys(), dict.values(), and dict.items() are OK. Just iterating over a dict (as in for key over dict1) returns the list of keys. Often used are sorted keys as in

keys = sorted(mydict)
Remi
  • 20,619
  • 8
  • 57
  • 41
  • `dict( (dict1[key], key) for key in dict1 )` i think this makes an additional value lookup – warvariuc Jul 21 '11 at 14:14
  • 'for key in dict' is not supposed to lookup any value, so the value is only looked for once: in dict1[key]. Avoiding using .items() makes the code just a bit "cleaner" for ease of reading. – Remi Jul 21 '11 at 14:22
  • yes, i think your are right - it does value lookup there only once. But still Python might have some optimizations when iterating over key-values pairs. But in this case: `dict( (dict1[key][-1], dict1[key][:-1]+[key]) for key in dict1 )` the lookup is done twice. – warvariuc Jul 22 '11 at 05:15
  • Correct. I just wanted to emphasize the more general answer for anyone who gets here because of the title of the question, for which I now gave two options. As for Python optimization: avoiding creation of an extra 'value' object is also a point, but to be fair, what happens under the hood can be any geniously optimized code, even depending on the Python version. This allows us, as programmers, to pay most attention to the readibility of or our own code. The difference between using 'dict[key]' and 'value - .items()' in this example comes close to personal preference and style. – Remi Jul 22 '11 at 12:15
0

And yet another approach:

dict1 = {'1': ['a','b', 'c', 'd'], '2': ['e','f', 'g', 'h']}
dict2 = {}

for k in dict1:

    dict2[dict1[k][-1]]= dict1[k]
    dict2[dict1[k][-1]][-1] = k

print dict2      #{'h': ['e', 'f', 'g', '2'], 'd': ['a', 'b', 'c', '1']}
Trufa
  • 39,971
  • 43
  • 126
  • 190