假设我有一个包含这些键和值的词典:
{'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'}}
答案 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)) }