是否有任何简单的方法来交换值列表的python字典键值

时间:2017-10-06 11:46:36

标签: python dictionary

有没有任何简单的方法来交换值列表的python字典键值 我的字典就像是

d={1:[1,2,3,4],2:[2,3,4],5:[1,3,6,7]}

我想从中生成一个字典,如下面的

a={1:[1,5],2:[1,2],3:[1,2,5],4:[1,2],6:[5],7:[5]}

我用反向测试

dict(map(reversed, d.items())

它不会迭代并使用列表中的项创建键返回TypeError:unhashable type:'list'

我正在寻找可用于实现此目的的任何内联方法

3 个答案:

答案 0 :(得分:3)

这将有效:

def revdict(d):
    r = {}
    for k in d:
        for v in d[k]:
            if v not in r:
                r[v] = [k]
            else:
                r[v].append(k)
    return r

然后你可以这样做:

d={1:[1,2,3,4],2:[2,3,4],5:[1,3,6,7]}
a = revdict(d)
print(a)

如果您想避免检查新密钥,可以使用defaultdict,然后始终附加。

答案 1 :(得分:2)

你的方法不起作用,因为在这里你的目标是构建一个字典:

{[1,2,3,4]: 1, [2,3,4]: 2, [1,3,6,7]: 5}

但是因为列表是不可用的,所以这些不能用作键(而且它不是你打算构建的那样)。

您可能最好使用defaultdict

from collections import defaultdict

result = defaultdict(list)
for k, vs in d.items():
    for v in vs:
        result[v].append(k)

在此操作之后,resultdefaultdict vanilla dict的子类),它将值列表中的项目映射到键(包含那个价值)。像:

>>> result
defaultdict(<class 'list'>, {1: [1, 5], 2: [1, 2], 3: [1, 2, 5], 4: [1, 2], 6: [5], 7: [5]})

您可以选择使用:

result = dict(result)

创建一个包含这些值的新词典(从而删除defaultdict)。

请注意:

  • 因为大多数Python解释器都没有对字典进行排序(这绝对不是你可以做出的一个很难的假设),所以列表中元素的顺序可能不同;和
  • 字典d中列表中的项目应为 hashable

答案 2 :(得分:0)

这不适合单线;通过称之为简单的逆转,你过度简化了你需要做的事情。

真正的反转只会将值映射到键而不是键值,您可以这样做(通过将列表轻微但必要的更改为元组):

>>> print dict((tuple(d[k]), k) for k in d)
{(1, 3, 6, 7): 5, (2, 3, 4): 2, (1, 2, 3, 4): 1}

你想要的东西要复杂得多,通常被称为dict的换位。

from operator import itemgetter as ig
from itertools import groupby

transposed_dict = dict((k, map(ig(1), v)) 
                       for k, v in groupby(
                                      sorted((nk, k) for k in d for nk in d[k]),
                                             key=ig(0)))

关于这一点并没有什么特别简单,虽然从概念上讲它并不太糟糕:

  1. (nk, k) for k in d for nk in d[k]从字典中创建扩展的关联列表,其中键和值已反转。

  2. groupby使用共同的第一个元素收集所有元组

  3. (k, map(ig(1), v))将具有共同第一个元素的元组收集到一个元组中:(1,1), (1,2) => (1, [1,2])

  4. 第3步中的元组用于构建新词典。

  5. 然而,使用Willem Van Onsem所示的简单的3行for循环,你会好得多;该循环的本质是sorted使用的生成器表达式;其他一切只是处理避免可变变量的尝试。并非所有事情都应该(或可以)简化为简单的单行。