有没有任何简单的方法可以在值为列表的地方交换python字典键值



有没有简单的方法可以交换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:不可处理类型:'list'

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

这将起作用:

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,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)

在这个操作之后,result是一个defaultdict(香草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中列表中的项目应该是可散列的

这并不适用于单行;你把你需要做的事情简单化了,称之为简单的逆转。

真正的反转只需将值映射到键,而不是键映射到值,您可以做到这一点(将列表略微但必要地更改为元组):

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

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

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. CCD_ 10将具有公共第一元素的元组收集为单个元组:CCD_。

  4. 步骤3中的元组用于构建新字典。

然而,使用Willem Van Onsem所示的简单的3线for循环会更好;该循环的本质在于CCD_ 13所使用的生成器表达式;其他一切都只是为了避免可变变量。不是所有的东西都应该(或可以)简化为一个简单的一行。

最新更新