代码之家  ›  专栏  ›  技术社区  ›  LucSpan

当值为列表且项不唯一时,交换字典键和值

  •  2
  • LucSpan  · 技术社区  · 7 年前

    组织

    我有一个大字典,在列表中有唯一键、唯一值和非唯一值。

    字典看起来像,

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

    问题

    我想交换键和值,

    d_inverse = {'1': ['a', 'b', 'c'], '2': ['a'],'3': ['a', 'c']}
    

    我找到了以下关于交换键和值的答案,

    关于用列表中的值交换键,

    最后一个答案很接近,但不管理列表中的非唯一值。

    也就是说,

    {k: oldk for oldk, oldv in d.items() for k in oldv}
    

    生产

    {'1': 'c', '2': 'a', '3': 'c'}
    

    如何解释非唯一值,并且不丢失信息?

    4 回复  |  直到 7 年前
        1
  •  4
  •   Aran-Fey Kevin    7 年前

    一种方法是使用 collections.defaultdict :

    d = {'a': ['1','2','3'],'b': ['1'],'c': ['1','3']}
    
    from collections import defaultdict
    d_dict = defaultdict(list)
    for k,v in d.items():
        for i in v:
            d_dict[i].append(k)
    
    dict(d_dict)
    #{'1': ['a', 'b', 'c'], '2': ['a'], '3': ['a', 'c']}
    
        2
  •  1
  •   Rakesh    7 年前

    使用 for-loop

    d = {'a': ['1','2','3'],'b': [1],'c': ['1','3']}
    res = {}
    
    for k,v in d.items():           #Iterate dictionary.
        for i in v:                 #Iterate List
            i = str(i)              #Convert element to string
            if i not in res:        #Check if key in dictionary.
                res[i] = [k]
            else:
                res[i].append(k)    #Else append element. 
    print(res)
    

    输出:

    {'1': ['a', 'c', 'b'], '3': ['a', 'c'], '2': ['a']}
    
        3
  •  1
  •   Maarten-vd-Sande    7 年前

    有人回答了这个问题 here

    inv_map = {}
    for k, v in my_map.iteritems():
        inv_map.setdefault(v, []).append(k)
    

    只需一点小小的改动,它就能按我们的要求工作:

    d = {'a': ['1','2','3'],'b': ['1'],'c': ['1','3']}
    
    inv_map = {}
    for k, vs in d.items():
        for v in vs:
            inv_map.setdefault(v, []).append(k)
    
    
    print(inv_map)
    >>> {'1': ['a', 'b', 'c'], '2': ['a'], '3': ['a', 'c']}
    
        4
  •  1
  •   Ajax1234    7 年前

    您还可以使用字典理解:

    from string import ascii_lowercase as alphabet
    d = {'a': ['1','2','3'],'b': ['1'],'c': ['1','3']}
    new_d = {str(alphabet.index(a)+1):[alphabet[int(i)-1] for i in b] for a, b in d.items()}
    

    输出:

    {'1': ['a', 'b', 'c'], '2': ['a'], '3': ['a', 'c']}