Python диктует удалить повторяющиеся значения по значению ключа? - PullRequest
3 голосов
/ 04 августа 2010

Дикт

dic = {
 1: 'a', 
 2: 'a', 
 3: 'b', 
 4: 'a', 
 5: 'c', 
 6: 'd', 
 7: 'd', 
 8: 'a', 
 9: 'a'}

Я хочу удалить повторяющиеся значения, оставив только одну пару K / V, Что касается выбора «ключа» этих дублированных значений, он может быть максимальным или минимальным, или случайным образом выбрать один из ключей этого дублированного элемента.

Я не хочу использовать своп k / v, поскольку он не может контролировать выбор ключа.

Взять значение "a", например

 1: 'a', 
 2: 'a', 
 4: 'a', 
 8: 'a', 
 9: 'a'

максимальный ключ будет {9: 'a'}, а минимальный будет {1: 'a'}, и случайный будет выбирать любой из них.

И, если ключ - это другой тип хешируемого значения, например, строка, то как сделать такой выбор?

Может кто-нибудь поделиться со мной идеей?

Спасибо!

Ответы [ 3 ]

5 голосов
/ 04 августа 2010

Вы можете создать обратный словарь, где значения являются списками всех ключей из вашего исходного словаря. Используя это, вы можете делать то, что вы хотите, мин, макс, случайное, чередование мин и макс или что угодно.

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]}
2 голосов
/ 04 августа 2010
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

Или другие функции «выбора» вместо min (что, конечно, работает нормально, даже если ключи являются строками - в этом случае вы получите клавишу «сначала лексически»).

Единственный случай, когда функция выбора нуждается в некотором внимании, - это когда ключи, соответствующие одному и тому же значению, могут быть несопоставимыми (например, комплексные числа или, в Python 3, объекты разных не-числовых типов) , Ничто из key= в min не вылечит; -).

1 голос
/ 04 августа 2010

Это даст вам случайно выбранный уникальный ключ:

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'}
...