有效地交换python dict的键和值,其中值包含一个或多个元素

时间:2013-07-26 04:51:23

标签: python algorithm dictionary

假设我有一个词典:

x =  { "a": ["walk", "the", "dog"], "b": ["dog", "spot"], "c":["the", "spot"]  }

并希望获得新的词典:

y = { "walk": ["a"], "the": ["a", "c"], "dog":["a", "b"], "spot":["b","c"]  }

最有效的方法是什么?如果一个解决方案是几行并且通过pythonic构造以某种方式简化它是什么(即使它不是最有效的)?

请注意,这与其他问题不同,其他值是单个元素而不是列表。

3 个答案:

答案 0 :(得分:5)

您可以使用defaultdict

from collections import defaultdict

y = defaultdict(list)

for key, values in x.items():  # .iteritems() in Python 2
    for value in values:
        y[value].append(key)

答案 1 :(得分:2)

y = {}
for (k, v) in x.iteritems():
    for e in v:
        y.setdefault(e, []).append(k)

我把它作为@Blender答案的替代品,因为它是我习惯使用的,但我认为Blender是优越的,因为它避免在内循环的每次传递中构造一个临时的[]。 / p>

答案 2 :(得分:1)

不一定效率,但只是为了好玩的一个班轮:

{b: [k for k, w in x.iteritems() if b in w] for v in x.values() for b in v}

这里的想法是迭代原始字典中的所有值(for v in x.values()),然后迭代列表中的所有项目(for b in v),然后使用b作为字典理解中的关键。 b的值是列表推导[k for ...],其中成员是字典x中的键,其值w包含单词b

由于范围有限,您实际上可以在上面写v而不是w,这使得它更难理解。 : - )

(编辑添加,我会使用@ Blender's。这一个内衬很有趣,但很难理解。)