Reputation: 33395
Given a collection of pairs of strings and (non-contiguous) integers, which are known in advance, a Python dictionary literal is a straightforward way to define a mapping from either to the other.
But supposing some parts of your program will have a string and want the corresponding integer, and others will have an integer and want the corresponding string, what's the best way to arrange this? Of course I could write out two separate dictionary literals, but that violates DRY, or I could do a bit of hacking with a function that uses globals() to create two dictionary variables from a single set of inputs, but I'm not sure how idiomatic that is. What's the recommended way? (I'm using Python 2.7 if it matters.)
Upvotes: 3
Views: 1072
Reputation: 365767
Instead of using a pair of dict
s, why not use an enum
?
Of course the stdlib enum
module requires 3.4, but its source is available to read and backport, or you can get the semi-official backport off PyPI, or any of the dozens of other enum
packages.
For example:
>>> import enum
>>> class Color(enum.Enum):
... red = 1
... green = 2
... blue = 3
>>> Color.red
<Color.red: 1>
>>> Color['red']
<Color.red: 1>
>>> Color(1)
<Color.red: 1>
>>> Color(1).name
'red'
>>> Color['red'].value
1
My guess is, most of the time you won't actually be mapping back and forth between these, but just using Color.red
, instead of your current "red"
or 1
, as a value. (If you want to be able to use the value directly as either an int
or a str
, look at the other classes in the docs.)
There should be good examples all over the 3.4 stdlib of how to convert code that used to use numbers and map them to strings and vice-versa into code that uses Enum
s instead. Unfortunately, as of 3.4b1, most of those examples haven't been written yet… I believe socket.AddressFamily
and a few related types are the only ones that have made it so far. But if you can't figure it out, show an MCVE, and it should be easy to show you how to convert it.
Upvotes: 5
Reputation: 2127
You can use bidict https://pypi.python.org/pypi/bidict to do this.
Upvotes: 5
Reputation: 122062
You could make the second mapping automatically from the first:
d2 = {v:k for k, v in d1.items()}
Upvotes: 5