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

在python3中反转字典中的键和值(值不是唯一的),python,python-3.x,dictionary,duplicates,key-value,Python,Python 3.x,Dictionary,Duplicates,Key Value,我知道当值是唯一的时,如何简单地反转字典中的键和值。 但是当值不唯一时如何反转。 根据要求,如果值出现多次,我需要使用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.ite

我知道当值是唯一的时,如何简单地反转字典中的键和值。 但是当值不唯一时如何反转。 根据要求,如果值出现多次,我需要使用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(已排序(倒置({'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()
def反转指令(d):
结果={}
对于d中的k:
如果d[k]不是结果:
结果[d[k]]=set()
结果[d[k]]。添加(k)
如果len(d[k])>1 else d[k],则返回{k:d[k]。d}中k的pop()
回溯(最近一次呼叫最后一次):
文件“U:\test.py”,第9行,在
打印(已排序(反转目录({'a':1,'b':2,'c':1}).items())
文件“U:\test.py”,第7行,倒过来
如果len(d[k])>1 else d[k],则返回{k:d[k]。d}中k的pop()
文件“U:\test.py”,第7行,在
如果len(d[k])>1 else d[k],则返回{k:d[k]。d}中k的pop()
TypeError:类型为“int”的对象没有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
,因此我预计,在这种情况下,应该这样做(例如)

补充:显然最新版本是至关重要的(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}
没什么难做的:只是用一个
pop
将singleton“解开”到他们的一个项目上(下一步是什么?另一个愚蠢的任意约束,如“no if/else expressions”?!-)

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

    return {k: result[k] if len(result[k])>1 else result[k].pop() for k in result}

答案是正确的!但是你能再做一次修改吗?我只想让这个键在集合多次出现时添加它。例如:输入:d={'a':1,'b':2,'c':1}输出应该是d={(1,{'a','c',,(2,'b')},并且你的输出是(1,{'a','c',(2,{'b'})。谢谢!而且…不允许导入是真的!多么有远见!您无法提前知道a
d[k]
是否会再次出现,因此,为了避免类型检查的恐怖,您需要一个后处理步骤——编辑a以显示这一点。嗯,出现错误:TypeError:int类型的对象没有len()在我发布的代码中,
d[k]
始终是一个
集合
,而不是一个
整数
。因此,如果您使用我的代码,您报告的错误就不会发生——因为它不会发生,所以我无法修复它。编辑您的Q以准确显示您正在运行的代码以及您得到的异常的完整回溯,我将修复您的错误(也许今晚不行,因为我马上就要睡觉了,但如果你跑得很快,也许明天早上就可以了。)我非常感谢你的帮助。我已经修改了我的问题。
    return {k: result[k] if len(result[k])>1 else result[k].pop() for k in result}