Reputation: 745
A dict
dic = {
1: 'a',
2: 'a',
3: 'b',
4: 'a',
5: 'c',
6: 'd',
7: 'd',
8: 'a',
9: 'a'}
I want to remove duplicate values just keep one K/V pair, Regarding the "key" selection of those duplicated values, it may be max or min or by random select one of those duplicated item's key.
I do not want to use a k/v swap since that can not control the key selection.
Take value "a" for example
1: 'a',
2: 'a',
4: 'a',
8: 'a',
9: 'a'
the max key will be {9: 'a'} and the min will be {1: 'a'}, and the random will choise any one of it.
And, if the key is other kind of hashable value, for example, string, then how to do such a selection?
Can anyone share me an idea?
Thanks!
Upvotes: 3
Views: 9592
Reputation: 69182
You could build a reverse dictionary where the values are lists of all the keys from your initial dictionary. Using this you could then do what you want, min, max, random, alternate min and max, or whatever.
from collections import defaultdict
d = defaultdict(list)
for k,v in dic.iteritems():
d[v].append(k)
print d
# {'a': [1, 2, 4, 8, 9], 'c': [5], 'b': [3], 'd': [6, 7]}
Upvotes: 5
Reputation: 879361
This will give you a randomly selected unique key:
In [29]: dic
Out[29]: {1: 'a', 2: 'a', 3: 'b', 4: 'a', 5: 'c', 6: 'd', 7: 'd', 8: 'a', 9: 'a'}
In [30]: dict((v,k) for k,v in dic.iteritems())
Out[30]: {'a': 9, 'b': 3, 'c': 5, 'd': 7}
In [31]: dict((v,k) for k,v in dict((v,k) for k,v in dic.iteritems()).iteritems())
Out[31]: {3: 'b', 5: 'c', 7: 'd', 9: 'a'}
Upvotes: 1
Reputation: 881575
import itertools as it
newdic = {}
for v, grp in it.groupby(sorted((v, k) for k, v in dic.items)):
newdic[min(k for _, k in grp)] = v
Or other "selection" functions in lieu of min
(which, of course, does work fine even if keys are strings -- will give you the "lexically first" key in that case).
The one case in which the selection function needs some care is when the keys corresponding to the same value may be non-comparable (e.g., complex numbers, or, in Python 3, objects of different not-all-numeric types). Nothing a key=
in the min
won't cure;-).
Upvotes: 2