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

如何将字典列表中每个ID的最后两条记录合并为指定格式

解决方法:提取每个ID的倒数第二和最后一条记录时间

我有如下Python列表:

import datetime
list1 = [
    {'id': 'ABC', 'created_at': datetime.datetime(2024, 8, 1, 11, 22, 3)},
    {'id': 'ABC', 'created_at': datetime.datetime(2024, 8, 2, 11, 22, 3)},
    {'id': 'ABC', 'created_at': datetime.datetime(2024, 8, 3, 11, 22, 3)},
    {'id': 'ABC', 'created_at': datetime.datetime(2024, 8, 5, 11, 22, 3)},
    {'id': 'BAC', 'created_at': datetime.datetime(2024, 7, 25, 18, 22, 3)},
    {'id': 'BAC', 'created_at': datetime.datetime(2024, 7, 26, 18, 22, 3)},
    {'id': 'BAC', 'created_at': datetime.datetime(2024, 8, 1, 18, 22, 3)},
    {'id': 'BAC', 'created_at': datetime.datetime(2024, 8, 5, 11, 22, 3)},
    {'id': 'CAB', 'created_at': datetime.datetime(2024, 8, 1, 6, 53, 3)},
    {'id': 'CAB', 'created_at': datetime.datetime(2024, 8, 1, 17, 53, 3)},
    {'id': 'CAB', 'created_at': datetime.datetime(2024, 8, 2, 11, 53, 3)},
    {'id': 'CAB', 'created_at': datetime.datetime(2024, 8, 5, 11, 22, 3)},
]

注:原代码中使用datetime.date传入时分秒参数会报错,这里修正为datetime.datetime以匹配时间格式。

该列表已按id和created_at排序,无需二次排序。

如果每个id仅出现一次,我知道可以这样处理:

output = '\n'.join([f"ID: {l['id']}, Created At: {l['created_at']}" for l in list1])

但我需要生成如下预期输出:

[
    {'id': 'ABC', 'start': datetime.datetime(2024, 8, 3, 11, 22, 3), 'end': datetime.datetime(2024, 8, 5, 11, 22, 3)},
    {'id': 'BAC', 'start': datetime.datetime(2024, 8, 1, 18, 22, 3), 'end': datetime.datetime(2024, 8, 5, 11, 22, 3)},
    {'id': 'CAB', 'start': datetime.datetime(2024, 8, 2, 11, 53, 3), 'end': datetime.datetime(2024, 8, 5, 11, 22, 3)},
]

需求是:将每个id的倒数第二条记录的日期作为start,最后一条记录的日期作为end。


实现代码

利用itertools.groupby对已排序的列表按id分组,再提取每个分组的倒数第二和最后一条记录的时间:

import datetime
from itertools import groupby

list1 = [
    {'id': 'ABC', 'created_at': datetime.datetime(2024, 8, 1, 11, 22, 3)},
    {'id': 'ABC', 'created_at': datetime.datetime(2024, 8, 2, 11, 22, 3)},
    {'id': 'ABC', 'created_at': datetime.datetime(2024, 8, 3, 11, 22, 3)},
    {'id': 'ABC', 'created_at': datetime.datetime(2024, 8, 5, 11, 22, 3)},
    {'id': 'BAC', 'created_at': datetime.datetime(2024, 7, 25, 18, 22, 3)},
    {'id': 'BAC', 'created_at': datetime.datetime(2024, 7, 26, 18, 22, 3)},
    {'id': 'BAC', 'created_at': datetime.datetime(2024, 8, 1, 18, 22, 3)},
    {'id': 'BAC', 'created_at': datetime.datetime(2024, 8, 5, 11, 22, 3)},
    {'id': 'CAB', 'created_at': datetime.datetime(2024, 8, 1, 6, 53, 3)},
    {'id': 'CAB', 'created_at': datetime.datetime(2024, 8, 1, 17, 53, 3)},
    {'id': 'CAB', 'created_at': datetime.datetime(2024, 8, 2, 11, 53, 3)},
    {'id': 'CAB', 'created_at': datetime.datetime(2024, 8, 5, 11, 22, 3)},
]

# 按id分组
grouped_records = groupby(list1, key=lambda item: item['id'])

result = []
for id_key, records in grouped_records:
    record_list = list(records)
    # 取倒数第二条的created_at作为start,最后一条作为end
    start_time = record_list[-2]['created_at']
    end_time = record_list[-1]['created_at']
    result.append({'id': id_key, 'start': start_time, 'end': end_time})

# 输出结果
print(result)

代码解释

  1. 分组:groupby基于已排序的列表,将相同id的记录归为一组,确保分组的连续性。
  2. 索引提取:将分组后的迭代器转为列表,通过负索引-2和-1快速获取倒数第二和最后一条记录的时间。
  3. 构造结果:将每个id对应的时间范围封装为字典,添加到结果列表中。

执行代码后即可得到预期的输出结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 05:30:54