如何通过键的值在Python字典中移除重复值?

3 投票
3 回答
9453 浏览
提问于 2025-04-16 02:17

一个字典

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

我想去掉重复的值,只保留一对键值对。关于那些重复值的“键”的选择,可以选择最大值、最小值,或者随机选择其中一个重复项的键。

我不想使用键值互换的方法,因为那样无法控制键的选择。

以值“a”为例

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

最大键会是 {9: 'a'},最小键会是 {1: 'a'},而随机选择则会从中选一个。

如果键是其他类型的可哈希值,比如字符串,那该如何进行这样的选择呢?

有没有人能给我一些建议?

谢谢!

3 个回答

1

这段代码会给你一个随机选出的独特的键值:

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

你可以创建一个反向字典,也就是说,把原来字典里的值变成一个列表,列表里包含所有对应的键。这样一来,你就可以根据这个反向字典来做你想做的事情,比如找最小值、最大值、随机值,或者交替取最小值和最大值,等等。

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
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(当然,min 也能正常工作,即使键是字符串——在这种情况下,它会给你“字典序最前”的键)。

需要特别注意的情况是,当对应同一个值的键可能无法比较时(例如,复数,或者在 Python 3 中,不同的非数字类型的对象)。不过,使用 min 中的 key= 参数就能解决这个问题;-)。

撰写回答