python - 使用字典理解反转一对多映射

标签 python python-3.x list dictionary

lst = [{'272': '4', '273': '4', '274': '4', '275': '5'}]
dct = {}

for k, v in lst[0].items():
    if dct.get(v) is None:
        dct.update({v: [k]})
    else:
        dct[v].append(k)

输出:

{'4': ['272', '273', '274'], '5': ['275']}

我还可以编写嵌套理解:

dct = {v: [k for (k, v1) in lst[0].items() if v1 == v]
          for (k, v) in lst[0].items()}

输出相同:

{'4': ['272', '273', '274'], '5': ['275']}** 

但是我们可以尝试在字典理解中使用单个 for 循环来获得相同的结果吗?

最佳答案

你不能一步完成字典理解中的同样的事情。您实际上是在反转字典,但由于原始字典中没有一对一的映射,因此您需要聚合每个值的重复键。

问题中的列表是一个转移注意力的内容。我要使用

d = {'272': '4', '273': '4', '274': '4', '275': '5'}

您可以采取几种方法。明智的做法是保持一个循环,但稍微简化一下。例如,您可以使用 collections.defaultdict ,就像常规的 dict ,除了它可以让您自动使用空值设置缺失的键:

from collections import defaultdict

result = defaultdict(list)
for k, v in d.items():
    result[v].append(k)

如果您使用几个标准库函数,您可以为此编写一个推导式。一种方法是使用 itertools.groupby ,但这需要您申请 sorted 第一:

from itertools import groupby
from operator import itemgetter

result = {k: list(map(itemgetter(0), vs))
              for k, vs in groupby(sorted(d.items(),
                                          key=itemgetter(1, 0)),
                                   itemgetter(1))}

operator.itemgetter 工作原理类似于 lambda x: x[0]大概在这里,但更快、更有效。

使用第二种解决方案,请注意,由于排序,时间复杂度从 O(n) 变为 O(n log n),并且为了获得“一行”而牺牲了很多易读性。

关于python - 使用字典理解反转一对多映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68939549/

相关文章:

c# - 有什么方法可以制作包含多个元素的 C# 列表?

Python:列表中完整字符串与部分字符串的交集

python - 如何保存 torchtext 数据集?

python - 如何让 CatBoost get_object_importance 与 AUC 配合使用?

python - ftp.retrbinary() 帮助 python

当进程数和工作线程数增加时,Python 多处理池 API 无法有效工作

python - 使用 input() 时出现 NameError

python-3.x - Keras - 基于用户输入的 EarlyStopping

python-3.x - Numba:如何抑制

java - 如何返回给定 HashMap 的有序列表?