按多个键对字典列表进行分组和聚合

新手上路,请多包涵

我有一个包含字典的列表( List[Dict, Dict, ...] ),我想根据两个键统一列表,但我想保留字典中另一个键的值以确保我不会丢失它通过在我想保留的密钥中列出一个列表。我正在使用 Python 作为代码。确切地说,如果它对 Python 3.x 有任何意义。

假设我有以下包含三个键的字典列表: numberfavoritecolor 。我想使用键 numberfavorite 来统一列表元素。但是对于具有相同值 numberfavorite 的字典,我想在键下添加一个列表 color color s 用于 numberfavorite 的相同组合。这个列表也应该是唯一的,因为它不需要重复的 color 相同的组合。但是,如果最终结果中的键颜色只有一个元素,则它应该是一个字符串而不是列表。

 lst = [
{'number': 1, 'favorite': False, 'color': 'red'},
{'number': 1, 'favorite': False, 'color': 'green'},
{'number': 1, 'favorite': False, 'color': 'red'},
{'number': 1, 'favorite': True, 'color': 'red'},
{'number': 2, 'favorite': False, 'color': 'red'}]

使用前面提到的 uniqify,我会得到以下结果:

 lst = [
    {'number': 1, 'favorite': False, 'color': {'red', 'green'}},
    {'number': 1, 'favorite': True, 'color': 'red'},
    {'number': 2, 'favorite': False, 'color': 'red'},
]

Note that there is only one instance of red where the number is 1 and favorite is False even though在被统一之前,它在列表中出现了两次。另请注意,当第二个字典中的键只有一个元素 color 时,它是一个字符串而不是列表。

原文由 KaanTheGuru 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

使用纯 python,您可以插入 OrderedDict 以保留插入顺序:

 from collections import OrderedDict

d = OrderedDict()
for l in lst:
    d.setdefault((l['number'], l['favorite']), set()).add(l['color'])

[{'number': k[0], 'favorite': k[1], 'color': v.pop() if len(v) == 1 else v}
    for k, v in d.items()]
# [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
#  {'color': 'red', 'favorite': True, 'number': 1},
#  {'color': 'red', 'favorite': False, 'number': 2}]


这也可以使用 pandas GroupBy API 轻松完成:

 import pandas as pd

d = (pd.DataFrame(lst)
       .groupby(['number', 'favorite'])
       .color
       .agg(set)
       .reset_index()
       .to_dict('r'))
d
# [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
#  {'color': {'red'}, 'favorite': True, 'number': 1},
#  {'color': {'red'}, 'favorite': False, 'number': 2}]

如果需要单个元素的字符串条件,可以使用

[{'color': (lambda v: v.pop() if len(v) == 1 else v)(d_.pop('color')), **d_}
     for d_ in d]
# [{'color': {'green', 'red'}, 'favorite': False, 'number': 1},
#  {'color': 'red', 'favorite': True, 'number': 1},
#  {'color': 'red', 'favorite': False, 'number': 2}]

原文由 cs95 发布,翻译遵循 CC BY-SA 4.0 许可协议

纯 Python 中的解决方案是使用 defaultdict 和复合键。你可以用它来合并你的价值观。之后您可以从该字典中再次创建一个列表。

 from collections import defaultdict

dct = defaultdict([])

for entry in lst:
    dct[(entry['number'], entry['favorite'])].append(entry['color'])

lst = [{'number': key[0], 'favorite': key[1], color: value if len(value) > 1 else value[0]}
    for key, value in dct.items()]

原文由 Praind 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题