在python3中反转字典中的键和值(值不唯一)

我知道当值是唯一的时,如何简单地在字典中反转键和值.
但是当值不唯一时如何反转.
根据要求,如果值出现不止一次,我需要使用set来将它们组合在一起.

防爆.输入d = {‘a’:1,’b’:2,’c’:1,’d’:2}输出d = {1,{‘a’,’c’},2,{‘b’ ,’C’}}

我在下面编写了相当愚蠢的代码,但因为我只创建了一个集合,因此所有显示多次的值都在该集合中.

def change(d):

    inverted_l = list(map(lambda t:(t[1],t[0]), d.items()))
    store_key = [] #for store the key to check if value appear more than one
    new_d = {}
    x = set()
    for i in range(len(inverted_l)):
        store_key.append(inverted_l[i][0])
    for i in range(len(store_key)):
        if store_key.count(store_key[i])> 1:
            x.add(inverted_l[i][1]) #I think the problem is I need create set
                                    #each time, but I don't know how to do that
            new_d[store_key[i]] = x
        else:
            new_d[store_key[i]] = inverted_l[i][1]
    return new_d

print(sorted(change({'a':1, 'b':2, 'c':1,'d':2}).items()))

我错误的输出是[(1,{‘c’,’d’,’b’,’a’}),(2,{‘c’,’d’,’b’,’a’})]但是我需要[(1,{‘a’,’c’}),(2,{‘b’,’d’})]

补充:我尝试你的代码,但是当我测试print时发生错误(sorted(invert_dict({‘a’:1,’b’:2,’c’:1}).items()))
我希望我的结果是[(1,{‘a’,’c’}),(2,’b’)]
我是python的新手,谢谢你的帮助和时间!

def invert_dict(d):
    result = {}
    for k in d:
        if d[k] not in result:
            result[d[k]] = set()
        result[d[k]].add(k)
    return {k: d[k] if len(d[k])>1 else d[k].pop() for k in d}



 Traceback (most recent call last):
  File "U:\test.py", line 9, in <module>
    print(sorted(invert_dict({'a':1, 'b':2, 'c':1}).items()))
  File "U:\test.py", line 7, in invert_dict
    return {k: d[k] if len(d[k])>1 else d[k].pop() for k in d}
  File "U:\test.py", line 7, in <dictcomp>
    return {k: d[k] if len(d[k])>1 else d[k].pop() for k in d}
TypeError: object of type 'int' has no len()

解决方法:

我很确定你的意思是所需的输出不是设定的

d = {1,{'a','c'},2,{'b','c'}}

而是字典

d = {1:{'a','c'}, 2:{'b','c'}}

只需仔细检查一下:-).

无论如何,我会这样做:

import collections

def invert_dict(d):
    result = collections.defaultdict(set)
    for k in d:
        result[d[k]].add(k)
    return dict(result)

如果dict子类defaultdict正常,则返回可以简化为返回结果 – 如果规范非常严格,则只需要将其转换为dict.

我想下一步可​​能是“oops,不允许导入”禁止集合.defaultdict,所以我预计 – 在这种情况下,请改为(例如)

def invert_dict(d):
    result = {}
    for k in d:
        if d[k] not in result:
            result[d[k]] = set()
        result[d[k]].add(k)
    return result

补充:显然最新版本是至关重要的(OP当然“忘记”首先添加“无导入”约束 – 为什么他们继续对我这样做?!它会花费他们任何东西来揭示所有的限制从他们的Qs开始前面?!?!?!!)但是需要进行调整 – 单例集需要转换成他们唯一元素的非集合(一个可怕的,可怕的,不好的规范,使得结果字典几乎无法使用,并且让我强烈希望对那些似乎相信制作令人作呕的糟糕规格改善他们的教学的没有好词的人有一些尖锐的话语,但是,这是另一种咆哮).

无论如何,最好是添加一个后处理步骤:

def invert_dict(d):
    result = {}
    for k in d:
        if d[k] not in result:
            result[d[k]] = set()
        result[d[k]].add(k)
    return {k: d[k] if len(d[k])>1 else d[k].pop() for k in d}

没有什么比这更难了:只需将“解开”单件套装设置为带有弹出的一个项目. (接下来是什么 – 另一个愚蠢的任意约束的迟来的启示,例如“no if / else表达式”?! – )

添加(保留上面的错误代码):需要在return语句中清楚地使用结果而不是d!即最后一行必须是

    return {k: result[k] if len(result[k])>1 else result[k].pop() for k in result}
上一篇:python – 删除列表中的重复数据帧


下一篇:java – Set可以包含重复项吗?