【问题标题】:python dict remove duplicate values by key's value?python dict按键值删除重复值?
【发布时间】:2011-03-25 01:26:12
【问题描述】:

一个字典

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'},随机选择其中任何一个。

而且,如果key是其他类型的hashable值,比如string,那么怎么做这样的选择呢?

谁能分享我的想法?

谢谢!

【问题讨论】:

  • 你能翻转它,让键是值,反之亦然吗?
  • OP 确实说“我不想使用 ak/v 交换,因为它无法控制键的选择” - 含糊不清,但我认为这意味着值可能是列表,或者dicts,或其他不能作为键的对象。

标签: python dictionary duplicates


【解决方案1】:

您可以构建一个反向字典,其中的值是初始字典中所有键的列表。使用它,你可以做你想做的事情,最小值、最大值、随机、交替的最小值和最大值,或其他任何东西。

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(当然,即使键是字符串,它也可以正常工作——在这种情况下会给你“词法优先”的键)。

    选择函数需要注意的一种情况是,对应于相同值的键可能是不可比较的(例如,复数,或者在 Python 3 中,不同的非全数字类型的对象) . min 中的任何 key= 都无法治愈;-)。

    【讨论】:

    • 感谢 Alex,我仍在尝试找出如何以您的方式随机选择重复的密钥。
    • @KC, random.choice(list(grp))[1] 是最简单的(当然有更好的 big-O 算法用于此目的,但是除非您的重复密钥组每个增长到数千个案例,否则部署它们是没有意义的键;-)。
    【解决方案3】:

    这会给你一个随机选择的唯一键:

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

    【讨论】:

    • 你能解释一下为什么 iteritem 返回随机数
    • @Registered:Python dicts 是无序的。因此,从 dic.iteritems() 发出键值对的顺序是不确定的。我应该说“未确定”而不是“随机”。
    • @Registered:我错过了您请求的方法不使用键值交换的事实。抱歉——这正是我上面所做的。我会把它留给你阅读,然后在一天左右删除。
    • @~ubuntu,你不必删除它,因为这是我以前不知道的好方法。
    猜你喜欢
    • 1970-01-01
    • 2013-05-22
    • 2015-06-23
    • 2017-11-07
    • 2018-04-10
    • 2021-12-26
    • 2019-07-26
    • 1970-01-01
    相关资源
    最近更新 更多