Maks
Maks

Reputation: 1

Swap keys for unique values in a dictionary in Python

a = {0: 'PtpMotion', 1: 'PtpMotion', 2: 'LinMotion', 3: 'LinMotion', 4: 'LinMotion', 5: 'LinMotion', 6: 'LinMotion', 7: 'LinMotion', 8: 'LinMotion', 9: 'PtpMotion', 10: 'LinMotion', 11: 'Wait'}
b = {}
for key, val in a.items():
    b[val] = key
print b

What I am trying to do is to swap value of the dictionary for key. But using this code, I lose some information of the dictionary, getting this output:

{'LinMotion': 10, 'PtpMotion': 9, 'Wait': 11}

Why does it happen?

Upvotes: 0

Views: 1770

Answers (4)

Sven Marnach
Sven Marnach

Reputation: 601809

Each key can only occur once in a dictionary. You could store a list of indices for each key:

import collections
b = collections.defaultdict(list)
for key, val in a.iteritems():
    b[val].append(key)
print b
# {'LinMotion': [2, 3, 4, 5, 6, 7, 8, 10], 'PtpMotion': [0, 1, 9], 'Wait': [11]}

Edit: As pointed out by ecik in the comments, you could also use a defaultdict(set) (and use .add() instead of .append() in the loop).

Upvotes: 4

Kathy Van Stone
Kathy Van Stone

Reputation: 26291

When you say

b[val] = key

and val already exists,it overrides the setting, getting what you see. To get all values, you must map the original values to lists of keys, such as

from collections import defaultdict

b = defaultdict(list)
for key, val in a.items():
    b[val].append(key)
print b

When I do it (python 2.5.1), I get

defaultdict(<type 'list'>, {'LinMotion': [2, 3, 4, 5, 6, 7, 8, 10], 
                            'PtpMotion': [0, 1, 9], 
                            'Wait': [11]})

Upvotes: 2

Russell Borogove
Russell Borogove

Reputation: 19037

Perhaps you want lists in the output dictionary:

from collections import defaultdict
a = {0: 'PtpMotion', 1: 'PtpMotion', 2: 'LinMotion', 3: 'LinMotion', 4: 'LinMotion', 5: 'LinMotion', 6: 'LinMotion', 7: 'LinMotion', 8: 'LinMotion', 9: 'PtpMotion', 10: 'LinMotion', 11: 'Wait'}
b = defaultdict(list)
for key, val in a.items():
    b[val].append(key)
print b

yields:

defaultdict(<type 'list'>, {'LinMotion': [2, 3, 4, 5, 6, 7, 8, 10], 'PtpMotion': [0, 1, 9], 'Wait': [11]})

Upvotes: 0

Brad Mace
Brad Mace

Reputation: 27886

Dictionary keys must be unique. If you wanted to keep them all you'd have to make each value for b[val] a list and add the values to those lists.

Upvotes: 1

Related Questions