首页 > 解决方案 > 在python字典中按值分组键/值对,保持原始键关联

问题描述

寻找一种有效的方法来根据它们的相似性对字典中的值进行分组,从而产生一个反向字典,其中原始键被分组为一个列表。我可以想到一些笨拙的方法来做到这一点,但对其他方法很感兴趣。

假设我的字典如下所示:

{'d1': {'goober': True, 'horse': 42},
 'd2': {'goober': True, 'horse': 42},
 'd3': {'goober': False, 'horse': 71}}

我想要的字典可能如下所示:

{'group1': {'dict': {'goober': True, 'horse': 42}, 'keys': ['d1', 'd2']},
 'group2': {'dict': {'goober': False, 'horse': 71}, 'keys': ['d3']}}

重要的细节是原始键d1d2已被分组在一个任意命名的 下group1,由原始字典中的相同字典分组。维护原始键 -d1d2存储在keys列表中 - 以及它们关联的字典也很重要。 d3是唯一的,因为它的字典是独一无二的。

我更大的目标是获取包含用于其他目的的参数的字典字典,但将它们分组到参数相同的位置,这样我可以更有效率并将它们一起运行。

任何提示或建议将不胜感激!

标签: pythondictionarygrouping

解决方案


这是可能的,但对于普通的 Python 来说很乏味。如果您愿意使用 3rd 方库,可以使用 Pandas 执行GroupBy聚合:

import pandas as pd

d = {'d1': {'goober': True, 'horse': 42},
     'd2': {'goober': True, 'horse': 42},
     'd3': {'goober': False, 'horse': 71}}

df = pd.DataFrame(d).T.reset_index().groupby('goober')\
                    .agg(lambda x: set(x)).reset_index()

print(df)

#   goober     index horse
# 0  False      {d3}  {71}
# 1   True  {d1, d2}  {42}

res = [{'dict': {'goober': row.goober, 'horse': next(iter(row.horse))},
        'keys': list(row.index)} for row in df.itertuples(index=False)]

结果:

[{'dict': {'goober': False, 'horse': 71}, 'keys': ['d3']},
 {'dict': {'goober': True, 'horse': 42}, 'keys': ['d1', 'd2']}]

注意我没有应用任何逻辑来派生'group1''group2'外部字典键。目前尚不清楚这些是如何得出的。如果它们是任意标识符,您可以enumerate在后续步骤中使用:

res2 = {f'group{idx}': d for idx, d in enumerate(res, 1)}

结果:

{'group1': {'dict': {'goober': False, 'horse': 71}, 'keys': ['d3']},
 'group2': {'dict': {'goober': True, 'horse': 42}, 'keys': ['d1', 'd2']}}

推荐阅读