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

时间:2015-01-28 04:21:12

标签: 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.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()

1 个答案:

答案 0 :(得分:5)

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

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)

如果return 子类 return result正常,dict可以简化为defaultdict - 只需要将其变为dict如果规范非常严格。

我想下一步可​​能是“哎呀,禁止进口”禁止collections.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}

没什么难的:只需“解开”单身人士设置为pop的一个项目。 (下一步 - 迟来的另一个愚蠢的任意约束的迟来的启示,例如“no if / else表达式”?! - )

已添加(保留上面的错误代码):需要在result语句中明确使用d而不是return!即最后一行必须是

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