如果键具有相同的值,如何合并和切换键值?

时间:2016-11-17 17:28:50

标签: python python-3.x dictionary

假设我有一个包含这些键和值的词典:

{'foo': 1, 'bar': 5,'foo1' : 1,'bar1' : 1,'foo2': 5}

我不能像这样压缩它们

dict(zip(my.values(),my.keys()))

因为这种情况发生了:

{1: 'foo', 5: 'bar'}

我想成为我的输出是:

{1:{'bar1','foo','foo1'},5:{'bar','foo2'}}

3 个答案:

答案 0 :(得分:5)

您应该使用collections.defaultdict()

from collections import defaultdict
result = defaultdict(list)
for k, v in my.items():
    result[v].append(k)

答案 1 :(得分:1)

给定键不能有多个值,因此这种数据结构中的值必须是列表。您无法使用zip()轻松完成此转换;你需要一个for循环:

my = {'foo': 1, 'bar': 5, 'foo1': 1, 'bar1': 1,'foo2': 5}
rev = {}

for k, v in my.items():
    rev.setdefault(v, []).append(k)

根据您问题中的修改,您似乎想要为值使用集合。这也很简单:

for k, v in my.items():
    rev.setdefault(v, set()).add(k)

你也可以像丹尼尔建议的那样使用defaultdict,但这里做导入似乎有些过分。根据字典的大小,它可能会快一点,因为使用setdefault()我们不断创建并丢弃空容器。

答案 2 :(得分:1)

对于具有功能性扭曲的单行程序(可能既不是最易读也不是高性能代码):

import itertools, operator

my_dict = {'foo': 1, 'bar': 5, 'foo1' : 1,'bar1' : 1, 'foo2': 5}

inverse_dict = { k:map(operator.itemgetter(0), v) for k, v in itertools.groupby(sorted(my_dict.items(), key=operator.itemgetter(1)), operator.itemgetter(1)) }

要使用集合进行聚合,只需将映射值包装在集合构造函数中。

inverse_dict = { k:set(map(operator.itemgetter(0), v)) for k, v in itertools.groupby(sorted(my_dict.items(), key=operator.itemgetter(1)), operator.itemgetter(1)) }