Python:按开始小时将对象列表分组为子列表的优化需求
优雅实现按开始时间小时分组Python列表元素
需求说明
需要将列表中的日程元素按照开始时间的小时是否与前一个元素不同进行分组:连续相同小时的元素归为一个子列表,小时变化时新建子列表。
输入示例
lst = [ { "start": "2022-08-03T09:00:00Z", "end": "2022-08-03T17:00:00Z" }, { "start": "2022-08-04T09:00:00Z", "end": "2022-08-04T17:00:00Z" }, { "start": "2022-08-05T15:30:00Z", "end": "2022-08-05T23:30:00Z" }, { "start": "2022-08-07T22:00:00Z", "end": "2022-08-08T06:00:00Z" } ]
期望输出
separated_lst = [ [ { "start": "2022-08-03T09:00:00Z", "end": "2022-08-03T17:00:00Z" }, { "start": "2022-08-04T09:00:00Z", "end": "2022-08-04T17:00:00Z" }, ], [ { "start": "2022-08-05T15:30:00Z", "end": "2022-08-05T23:30:00Z" }, ], [ { "start": "2022-08-07T22:00:00Z", "end": "2022-08-08T06:00:00Z" } ] ]
原实现方案
已实现的可行但不够简洁的代码:
separated_shifts = [[]] previous_shift = None counter = 0 for shift in shifts: shift_start = self._format_date(shift["start"]) if self.__is_different_shift(shift_start, previous_shift): counter += 1 separated_shifts.append([]) separated_shifts[counter].append(shift) previous_shift = shift_start
优化方案
利用Python标准库itertools.groupby,可以实现更简洁、可读性更强的代码:
代码实现
from itertools import groupby import datetime def group_by_start_hour(shifts): # 定义分组key:提取开始时间的小时数 def get_hour(shift): # 解析带时区的ISO格式时间字符串 dt = datetime.datetime.fromisoformat(shift["start"].replace("Z", "+00:00")) return dt.hour # 按连续相同小时分组,转换为列表形式 return [list(group) for _, group in groupby(shifts, key=get_hour)] # 调用示例 separated_lst = group_by_start_hour(lst)
方案优势
- 代码简洁:用一行列表推导式完成分组逻辑,避免手动维护计数器和分组列表
- 可读性强:依赖标准库工具,逻辑清晰,一眼就能看出是按开始小时分组
- 可扩展性高:如需调整分组规则,只需修改
get_hour函数的返回值即可
如果你的_format_date方法已经实现了时间解析,可以直接替换get_hour中的时间解析逻辑,比如:
def get_hour(shift): dt = self._format_date(shift["start"]) return dt.hour
内容的提问来源于stack exchange,提问作者anderex92
相关产品推荐
相关产品推荐

