11

我想反转字典的键和值。即来自源字典Dictionary<int, string>,我想得到Dictionary<string, List<int>>。这是List<int>因为该值可以在不同的键下多次出现在源字典中。

例子:

{
  1: "A"
  2: "A"
  3: "A"
  4: "B"
  5: "B"
  6: "C"
  7: "D"
}

将转变为:

{
  "A": [1,2,3]
  "B": [4,5]
  "C": [6]
  "D": [7]
}

感谢帮助。

编辑:

好的,在你们的帮助下,我对这个算法有了一些了解。现在我看到了两种可能的解决方案(除其他外)并且不知道它们之间的真正区别是什么,因为结果似乎是相同的。

是否存在性能问题?

var byLookup = actions.ToLookup(pair => pair.Value, pair => pair.Key)
    .ToDictionary(group => group.Key, group => group.AsEnumerable());
var byGroupBy = actions.GroupBy(pair => pair.Value, pair => pair.Key)
    .ToDictionary(group => group.Key, group => group.AsEnumerable());

编辑2:

我最终只使用了

var byLookup = actions.ToLookup(pair => pair.Value, pair => pair.Key)

我没想到会这么简单。谢谢大家。

4

3 回答 3

27

这是一个相当简单的 LINQ 表达式:

var res = dict
    .GroupBy(p => p.Value)
    .ToDictionary(g => g.Key, g => g.Select(pp => pp.Key).ToList());

首先,您按值分组。这将创建以字符串作为键和KeyValuePair<int,string>作为其项的组。

然后,您通过使用组的键作为字典键将组转换为字典,并将原始字典的键“展平”为带有ToList().

于 2013-10-22T12:58:10.547 回答
4

您还可以获得所需的结果,如下所示:

var result = source
    .GroupBy(x => x.Value, x => x.Key)
    .ToDictionary(g => g.Key, g => g.ToList());

这给出了与dasblinkenlight相同的结果,但将 KeyValuePair 的映射移动到 group by 子句中

于 2013-10-22T13:11:09.257 回答
-3
dic = {1: "A",  2: "A",  3: "A",  4: "B",  5: "B",  6: "C",  7: "D"}

rev_dic = {}
for key in dic:
    new_value = dic[key]
    if not new_value in rev_dic:
        rev_dic[new_value] = []
    rev_dic[new_value].append(key)

for new_value in rev_dic:
    rev_dic[new_value].sort()

print(rev_dic)

将打印:

{'A': [1, 2, 3], 'B': [4, 5], 'C': [6], 'D': [7]}
于 2020-01-03T12:26:36.293 回答