196

For the tuple, t = ((1, 'a'),(2, 'b')) dict(t) returns {1: 'a', 2: 'b'}

Is there a good way to get {'a': 1, 'b': 2} (keys and vals swapped)?

Ultimately, I want to be able to return 1 given 'a' or 2 given 'b', perhaps converting to a dict is not the best way.

Jake
  • 12,713
  • 18
  • 66
  • 96

7 Answers7

354

Try:

>>> t = ((1, 'a'),(2, 'b'))
>>> dict((y, x) for x, y in t)
{'a': 1, 'b': 2}
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 8
    +1 Beautiful!, I had to try it with zip `dict(zip(*zip(*t)[::-1]))`. This is slower, uglier and using way more memory..likely 3x. – kevpie Apr 28 '11 at 01:35
  • @kevpie The wonderful thing about Python is that there are a hundred ways to express how to do something, each just as interesting as the next. – bjd2385 Jan 18 '17 at 23:30
  • Great, if what you have a is a triple you can do: `dict((x, y) for x, y, z in t)` or `dict((x, (y, z)) for x, y, z in t)` to get the second and third values as a tuple. – gdvalderrama Mar 28 '18 at 08:15
  • 2
    Also possible with a dict literal instead of a dict constructor: `{y: x for x, y in t}` – jnns Dec 16 '20 at 15:30
  • 1
    @bjd2385 Actually, this is a bit of a contradiction to clause 13 of PEP 20 (`import this`) ... All the same, it's true what you're saying. – mara004 Jan 16 '23 at 16:52
92

A slightly simpler method:

>>> t = ((1, 'a'),(2, 'b'))
>>> dict(map(reversed, t))
{'a': 1, 'b': 2}
jterrace
  • 64,866
  • 22
  • 157
  • 202
  • 1
    what makes this faster ? – maazza Aug 21 '13 at 12:59
  • 12
    The map and dict functions are implement in C and are much faster than any python version – jterrace Aug 21 '13 at 14:32
  • 4
    I like this for having the `reverse` explicitely spelled out. – Frerich Raabe Nov 28 '13 at 10:56
  • 8
    @maazza: in general, performance tests suggest that (in the C implementation at least) `map` is faster than a comprehension when the thing being mapped is another built-in function (like `reversed`); in most other cases, the opposite is true. But it's better to profile than guess :) – Karl Knechtel Jan 23 '14 at 02:00
  • Nice! However, to my preference, the `for` expression looks slightly more obvious. – mara004 Jan 14 '23 at 15:16
53

Even more concise if you are on python 2.7:

>>> t = ((1,'a'),(2,'b'))
>>> {y:x for x,y in t}
{'a':1, 'b':2}
autholykos
  • 836
  • 8
  • 14
18
>>> dict([('hi','goodbye')])
{'hi': 'goodbye'}

Or:

>>> [ dict([i]) for i in (('CSCO', 21.14), ('CSCO', 21.14), ('CSCO', 21.14), ('CSCO', 21.14)) ]
[{'CSCO': 21.14}, {'CSCO': 21.14}, {'CSCO': 21.14}, {'CSCO': 21.14}]
Smi
  • 13,850
  • 9
  • 56
  • 64
Gunnarsson
  • 538
  • 5
  • 5
  • You misunderstood the question - the point is how to swap keys and values. This simple conversion is already stated in the question itself. – mara004 Jan 14 '23 at 15:13
7

If there are multiple values for the same key, the following code will append those values to a list corresponding to their key,

d = dict()
for x,y in t:
    if(d.has_key(y)):
        d[y].append(x)
    else:
        d[y] = [x]
psun
  • 615
  • 10
  • 13
3

Here are couple ways of doing it:

>>> t = ((1, 'a'), (2, 'b'))

>>> # using reversed function
>>> dict(reversed(i) for i in t)
{'a': 1, 'b': 2}

>>> # using slice operator
>>> dict(i[::-1] for i in t)
{'a': 1, 'b': 2}
Vlad Bezden
  • 83,883
  • 25
  • 248
  • 179
-1

With Python 3.6 and above, it's a function:

mydict=myty._asdict()
Vinayak Thatte
  • 496
  • 6
  • 5