You need to enable JavaScript to run this app. 如何将业务日期列表转换为连续业务周期组成的嵌套列表
优惠活动
大模型
产品
解决方案
定价
更多

如何将业务日期列表转换为连续业务周期组成的嵌套列表

最优实现方案

你的核心拆分规则是:相邻两个输入的工作日之间,如果存在至少1个未被收录的普通工作日(周一到周五,不含周末),就拆分新周期;如果间隔的都是周末,就算自然日差大也不拆分——这和你给的示例完全匹配:

  • 17/02/2021(周三)和19/02/2021(周五)中间夹了18号(周四,工作日、未在列表),触发拆分
  • 19/02/2021(周五)和22/02/2021(周一)中间夹了20、21号周末,没有符合条件的间隔工作日,不拆分

基于这个规则,最优实现是O(n)一次遍历的方案,没有冗余计算,兼容常见的格式问题,不需要引入第三方依赖。

实现步骤

  1. 前置数据清洗:你的原始列表里最后一个日期带了前导空格" 23/02/2021",先统一对所有日期字符串做去空格处理,再转成可计算的日期对象,同时把清洗后的日期存成集合,方便快速校验是否在列表里。
  2. 遍历拆分周期:
    • 空输入直接返回空结果;单日期输入直接返回单元素周期。
    • 初始化当前周期的起始日期为列表第一个元素,从第二个元素开始逐个校验相邻的两个日期对:
      • 统计两个日期之间夹的、没在列表里的工作日数量
      • 如果统计值≥1:闭合当前周期(起始日期为初始值,结束日期为上一个相邻日期),把周期加入结果,再把新周期的起始日期设为当前遍历的日期
      • 如果统计值为0:说明是同个连续周期,继续向后遍历即可
    • 所有元素遍历完成后,把最后一个未闭合的周期加入结果列表。
  3. 格式适配:按你需要的输出格式整理每个周期的start、end字段。

参考可运行代码

from datetime import datetime, timedelta

# 原始输入列表
list_of_dates = ["15/02/2021", "16/02/2021", "17/02/2021",
                 "19/02/2021", "22/02/2021", " 23/02/2021"]

# 前置清洗:统一去空格、转datetime对象
clean_dates = [datetime.strptime(d.strip(), "%d/%m/%Y") for d in list_of_dates]
date_set = {d.strftime("%d/%m/%Y") for d in clean_dates}

def count_missing_workday(prev_date: datetime, curr_date: datetime) -> int:
    """计算两个相邻日期间,有多少个未被收录的工作日(自动跳过周末)"""
    missing_count = 0
    check_day = prev_date + timedelta(days=1)
    while check_day < curr_date:
        # weekday()返回0=周一,4=周五,属于工作日;5/6是周末
        if check_day.weekday() < 5:
            day_str = check_day.strftime("%d/%m/%Y")
            if day_str not in date_set:
                missing_count += 1
        check_day += timedelta(days=1)
    return missing_count

# 核心拆分逻辑
list_of_periods = []
if clean_dates:
    current_start = clean_dates[0]
    for idx in range(1, len(clean_dates)):
        prev = clean_dates[idx-1]
        curr = clean_dates[idx]
        # 满足拆分条件:存在至少1个漏录的工作日
        if count_missing_workday(prev, curr) >= 1:
            list_of_periods.append({
                "start_date": current_start.strftime("%d/%m/%Y"),
                "end_date": prev.strftime("%d/%m/%Y")
            })
            current_start = curr
    # 补全最后一个周期
    list_of_periods.append({
        "start_date": current_start.strftime("%d/%m/%Y"),
        "end_date": clean_dates[-1].strftime("%d/%m/%Y")
    })

# 运行输出完全匹配预期格式
# [{'start_date': '15/02/2021', 'end_date': '17/02/2021'}, {'start_date': '19/02/2021', 'end_date': '23/02/2021'}]

方案优势

  • 性能最优:整体仅一次遍历输入列表,没有嵌套循环,哪怕处理上万条工作日数据也能毫秒级响应
  • 无第三方依赖:完全使用Python内置标准库,不需要额外安装包,部署零成本
  • 鲁棒性强:自动处理带前后空格的格式脏数据,不会因为输入格式小问题导致解析失败
  • 规则匹配精度高:严格按照“间隔未收录工作日才拆分”的逻辑判断,不会出现把周末间隔当成拆分条件的错误

注意:你原写法里的目标格式存在语法问题——直接在列表项里写start_date="xxx"的语法无法被Python识别,实际使用时需要替换为标准字典格式,也就是上面代码里的实现方式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 23:54:04