Suppose I have a dict:
假设我有一个词典:
x = { "a": ["walk", "the", "dog"], "b": ["dog", "spot"], "c":["the", "spot"] }
and want to have the new dict:
并希望有新的词典:
y = { "walk": ["a"], "the": ["a", "c"], "dog":["a", "b"], "spot":["b","c"] }
What is the most efficient way to do this? If a solution is a few lines and is somehow made simple by a pythonic construct what is it (even if it's not most efficient)?
最有效的方法是什么?如果解决方案是几行并且通过pythonic构造以某种方式简化它是什么(即使它不是最有效的)?
Note that this is different than other questions where the value is a single element and not a list.
请注意,这与其他值是单个元素而不是列表的问题不同。
3 个解决方案
#1
5
You can use defaultdict
:
你可以使用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)
#2
2
y = {}
for (k, v) in x.iteritems():
for e in v:
y.setdefault(e, []).append(k)
I presented this as an alternative to @Blender's answer, since it's what I'm accustomed to using, but I think Blender's is superior since it avoids constructing a temporary []
on every pass of the inner loop.
我把它作为@Blender答案的替代品,因为它是我习惯使用的,但我认为Blender是优越的,因为它避免在内循环的每次传递中构造临时[]。
#3
1
Not necessarily efficient, but a one liner just for fun:
不一定高效,但只是为了好玩的一个班轮:
{b: [k for k, w in x.iteritems() if b in w] for v in x.values() for b in v}
The idea here is to iterate over all the values in the original dictionary (for v in x.values()
), then iterate over all the items in the list (for b in v
), then use b
as the key in a dict-comprehension. The value for b
is a list comprehension [k for ...]
where the members are the keys in dictionary x
for which the value w
contains the word b
.
这里的想法是迭代原始字典中的所有值(对于x.values()中的v),然后遍历列表中的所有项(对于v中的b),然后使用b作为字典中的键-理解。 b的值是列表推导[k for ...],其中成员是字典x中的键,其值w包含单词b。
Because the scope is limited you can actually write v
instead of w
above, which makes it even harder to understand. :-)
因为范围是有限的,你实际上可以写v而不是上面的w,这使得它更难理解。 :-)
(Edit to add, I'd use @Blender's. These one liners are fun, but really hard to grok.)
(编辑添加,我会使用@Blender's。这些衬里很有趣,但很难理解。)
#1
5
You can use defaultdict
:
你可以使用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)
#2
2
y = {}
for (k, v) in x.iteritems():
for e in v:
y.setdefault(e, []).append(k)
I presented this as an alternative to @Blender's answer, since it's what I'm accustomed to using, but I think Blender's is superior since it avoids constructing a temporary []
on every pass of the inner loop.
我把它作为@Blender答案的替代品,因为它是我习惯使用的,但我认为Blender是优越的,因为它避免在内循环的每次传递中构造临时[]。
#3
1
Not necessarily efficient, but a one liner just for fun:
不一定高效,但只是为了好玩的一个班轮:
{b: [k for k, w in x.iteritems() if b in w] for v in x.values() for b in v}
The idea here is to iterate over all the values in the original dictionary (for v in x.values()
), then iterate over all the items in the list (for b in v
), then use b
as the key in a dict-comprehension. The value for b
is a list comprehension [k for ...]
where the members are the keys in dictionary x
for which the value w
contains the word b
.
这里的想法是迭代原始字典中的所有值(对于x.values()中的v),然后遍历列表中的所有项(对于v中的b),然后使用b作为字典中的键-理解。 b的值是列表推导[k for ...],其中成员是字典x中的键,其值w包含单词b。
Because the scope is limited you can actually write v
instead of w
above, which makes it even harder to understand. :-)
因为范围是有限的,你实际上可以写v而不是上面的w,这使得它更难理解。 :-)
(Edit to add, I'd use @Blender's. These one liners are fun, but really hard to grok.)
(编辑添加,我会使用@Blender's。这些衬里很有趣,但很难理解。)