Say I have a dictionary like so:
my_dict = {2:3, 5:6, 8:9}
Is there a way that I can switch the keys and values to get:
{3:2, 6:5, 9:8}
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
For Python 3:
my_dict2 = {y: x for x, y in my_dict.items()}
For Python 2, you can use
my_dict2 = dict((y, x) for x, y in my_dict.iteritems())
Method 2
my_dict = { my_dict[k]:k for k in my_dict}
Method 3
Try this:
my_dict = {2:3, 5:6, 8:9}
new_dict = {}
for k, v in my_dict.items():
new_dict[v] = k
Method 4
Use this code (trivially modified) from the accepted answer at Python reverse / invert a mapping:
dict((v,k) for k, v in my_dict.iteritems())
Note that this assumes that the values in the original dictionary are unique. Otherwise you’d end up with duplicate keys in the resulting dictionary, and that is not allowed.
And, as @wim points out, it also assumes the values are hashable. See the Python glossary if you’re not sure what is and isn’t hashable.
Method 5
maybe:
flipped_dict = dict(zip(my_dict.values(), my_dict.keys()))
Method 6
First of all it is not guaranteed that this is possible, since the values of a dictionary can be unhashable.
In case these are not, we can use a functional approach with:
reversed_dict = dict(map(reversed, original_dict.items()))
Method 7
Sometimes, the condition that the values are all unique will not hold, in which case, the answers above will destroy any duplicate values.
The following rolls the values that might be duplicates up into a list:
from itertools import count dict([(a,[list(d.keys())[i] for i,j in zip(count(), d.values())if j==a in set(d.values())])
I’m sure there’s a better (non-list-comp) method, but I had a problem with the earlier answers, so thought I’d provide my solution in case others have a similar use-case.
P.S. Don’t expect the dict to remain neatly arranged after any changes to the original! This method is a one-time use only on a static dict – you have been warned!
Method 8
If the values are not unique this will collide the key space in conversion.
Best is to keep the keys in list when switching places
below handles this –
RvsD = dict()
for k,v in MyDict.iteritems():
RsvD.setdefault(v, []).append(k)
Method 9
You can do it like this:
Function:
def inverse_dict(my_dict):
updated_dict = {}
for i in my_dict:
updated_dict[my_dict[i]] = [i]
return updated_dict
Main():
def main():
year = {'day': 15, 'month': 3, 'year': 2019}
print(inverse_dict(year))
if __name__ == "__main__":
main()
Ouput:
{15: ['day'], 3: ['month'], 2019: ['year']}
Method 10
If values are not unique in the dictionary, then you can map keys to that value. Here an example of how to do it using defaultdict
from collections import defaultdict
def reverse_dict(data: dict) -> dict:
rd = defaultdict(list)
for k, v in data.items():
rd[v].append(k)
return rd
if __name__ == "__main__":
from collections import Counter
data = "aaa bbb ccc ddd aaa bbb ccc aaa"
c = Counter(data.split())
print(c)
# Counter({'aaa': 3, 'bbb': 2, 'ccc': 2, 'ddd': 1})
rd = reverse_dict(c)
print(rd)
# defaultdict(<class 'list'>, {3: ['aaa'], 2: ['bbb', 'ccc'], 1: ['ddd']})
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0