You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python字典列表按ID分组并新增键值对的实现问题

问题:按ID分组字典列表并统计演出状态计数

从数据库查询得到一个字典列表,需要按id字段对数据进行分组,并基于字典中的现有数据添加past_shows、upcoming_shows等新键值对及对应计数。现有代码未达到预期效果,寻求正确实现方案。


原始数据示例

raw_data = [
    {"id": 1, "show_date": "2023-01-01", "status": "past"},
    {"id": 1, "show_date": "2023-06-01", "status": "upcoming"},
    {"id": 2, "show_date": "2022-12-01", "status": "past"},
    {"id": 2, "show_date": "2023-07-01", "status": "upcoming"},
    {"id": 2, "show_date": "2023-08-01", "status": "upcoming"},
]

期望输出结果

expected_output = [
    {
        "id": 1,
        "past_shows": 1,
        "upcoming_shows": 1,
        "shows": [
            {"show_date": "2023-01-01", "status": "past"},
            {"show_date": "2023-06-01", "status": "upcoming"}
        ]
    },
    {
        "id": 2,
        "past_shows": 1,
        "upcoming_shows": 2,
        "shows": [
            {"show_date": "2022-12-01", "status": "past"},
            {"show_date": "2023-07-01", "status": "upcoming"},
            {"show_date": "2023-08-01", "status": "upcoming"}
        ]
    }
]

尝试的代码(未达到预期)

# 示例错误代码(常见逻辑问题)
result = []
for item in raw_data:
    existing = next((r for r in result if r["id"] == item["id"]), None)
    if not existing:
        # 错误:初始化时可能未正确设置计数初始值,或后续计数逻辑遗漏
        result.append({
            "id": item["id"],
            "past_shows": 0,
            "upcoming_shows": 0,
            "shows": []
        })
        existing = result[-1]
    existing["shows"].append(item)
    # 错误:可能未正确匹配status值,或计数逻辑触发条件错误
    if item.get("status") == "past":
        existing["past_shows"] += 1

正确实现方案

方法一:使用字典映射分组(高效处理无序数据)

这种方法不需要预先排序,直接通过字典记录每个ID对应的分组信息,适合处理大规模或无序数据:

def process_shows(raw_data):
    grouped_dict = {}
    for item in raw_data:
        show_id = item["id"]
        # 初始化分组条目(如果ID未存在)
        if show_id not in grouped_dict:
            grouped_dict[show_id] = {
                "id": show_id,
                "past_shows": 0,
                "upcoming_shows": 0,
                "shows": []
            }
        # 添加当前演出到列表
        grouped_dict[show_id]["shows"].append(item)
        # 根据状态更新计数
        status = item["status"]
        if status == "past":
            grouped_dict[show_id]["past_shows"] += 1
        elif status == "upcoming":
            grouped_dict[show_id]["upcoming_shows"] += 1
    # 将字典值转换为列表返回
    return list(grouped_dict.values())

方法二:使用itertools.groupby(代码简洁,需先排序)

groupby要求数据按分组键连续排列,因此需要先对原始数据按id排序,适合数据本身已排序或对代码简洁性要求较高的场景:

from itertools import groupby
from operator import itemgetter

def process_shows(raw_data):
    # 先按id排序,确保groupby能正确分组
    sorted_data = sorted(raw_data, key=itemgetter("id"))
    result = []
    for show_id, group in groupby(sorted_data, key=itemgetter("id")):
        shows_list = list(group)
        # 统计不同状态的演出数量
        past_count = sum(1 for show in shows_list if show["status"] == "past")
        upcoming_count = sum(1 for show in shows_list if show["status"] == "upcoming")
        # 组装结果条目
        result.append({
            "id": show_id,
            "past_shows": past_count,
            "upcoming_shows": upcoming_count,
            "shows": shows_list
        })
    return result

测试验证

调用上述函数并传入原始数据,即可得到与期望输出一致的结果:

raw_data = [
    {"id": 1, "show_date": "2023-01-01", "status": "past"},
    {"id": 1, "show_date": "2023-06-01", "status": "upcoming"},
    {"id": 2, "show_date": "2022-12-01", "status": "past"},
    {"id": 2, "show_date": "2023-07-01", "status": "upcoming"},
    {"id": 2, "show_date": "2023-08-01", "status": "upcoming"},
]

print(process_shows(raw_data))

内容的提问来源于stack exchange,提问作者Emmanuel Folorunsho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 13:10:28