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

如何更优雅地根据globalDepots拆分route路径列表?

更简洁优雅的Python路线拆分实现方案

需求说明

我需要将以下route列表:

route = [51, 5, 33, 39, 34, 32, 64, 53, 62, 66, 58, 59, 54, 38, 9, 21, 29, 2, 61, 11, 50, 16, 20, 28, 31, 8, 26, 43, 7, 1, 27, 60, 55, 52, 10, 30, 49, 46, 12, 15, 44, 45, 37, 56, 65, 63, 42, 19, 40, 41, 13, 25, 14, 18, 57, 48, 23, 24, 6, 3, 36, 35, 22, 17, 4, 47]

按照globalDepots列表(包含50到65的整数):

globalDepots = [i for i in range(50, 66)]

的元素位置拆分成多个miniRoute子列表,预期输出结果如下:

Total number of valid miniRoutes is 16
All mini routes: 
#1   [51, 5, 33, 39, 34, 32, 64]
#2   [64, 53]
#3   [53, 62]
#4   [62, 66, 58]
#5   [58, 59]
#6   [59, 54]
#7   [54, 38, 9, 21, 29, 2, 61]
#8   [61, 11, 50]
#9   [50, 16, 20, 28, 31, 8, 26, 43, 7, 1, 27, 60]
#10  [60, 55]
#11  [55, 52]
#12  [52, 10, 30, 49, 46, 12, 15, 44, 45, 37, 56]
#13  [56, 65]
#14  [65, 63]
#15  [63, 42, 19, 40, 41, 13, 25, 14, 18, 57]
#16  [57, 48, 23, 24, 6, 3, 36, 35, 22, 17, 4, 47, 50]

现有脚本可实现该功能,但希望获得更简洁优雅的实现方式,当前代码如下:

当前实现代码

import random

def countMiniRoutes(route):
    depotIndexes = []
    for depot in globalDepots:
        index = route.index(depot)
        depotIndexes.append(index)
    miniRoutesList = []
    sortedDepotIndexes = sorted(depotIndexes)
    start = sortedDepotIndexes[0]
    if route[-1] not in globalDepots:
        route.append(globalDepots[0])

    for i, depotIndex in enumerate(sortedDepotIndexes):
        try:
            stop = sortedDepotIndexes[i+1]+1
        except IndexError:
            stop = len(route)
        miniRoute = route[start:stop]
        try:
            dist = random.random()
            miniRoutesList.append(miniRoute)
        except ZeroDivisionError:
            # if dist == 0, then do not add it to miniRoutesList
            continue
        try:    
            start = sortedDepotIndexes[i+1]
        except IndexError:
            start = sortedDepotIndexes[i]
            
    print(f"Total number of valid miniRoutes is {len(miniRoutesList)}")
    print("All mini routes: ")
    for i, route in enumerate(miniRoutesList):
        print(f"#{i+1} \t {route}")

if __name__ == "__main__":
    globalDepots = [i for i in range(50, 66)]
    route = [51, 5, 33, 39, 34, 32, 64, 53, 62, 66, 58, 59, 54, 38, 9, 21, 29, 2, 61, 11, 50, 16, 20, 28, 31, 8, 26, 43, 7, 1, 27, 60, 55, 52, 10, 30, 49, 46, 12, 15, 44, 45, 37, 56, 65, 63, 42, 19, 40, 41, 13, 25, 14, 18, 57, 48, 23, 24, 6, 3, 36, 35, 22, 17, 4, 47]
    countMiniRoutes(route)

优化后的实现代码

import random

def split_route(route, depots):
    # 转换为集合提升成员判断效率
    depot_set = set(depots)
    # 复制原路线避免修改输入列表
    working_route = route.copy()
    # 如果路线末尾不是 depot,添加第一个 depot 作为终点
    if working_route[-1] not in depot_set:
        working_route.append(depots[0])
    
    # 收集所有 depot 在路线中的索引并排序
    depot_indices = sorted(idx for idx, val in enumerate(working_route) if val in depot_set)
    mini_routes = []
    
    # 遍历连续的索引对生成子路线
    for start_idx, end_idx in zip(depot_indices[:-1], depot_indices[1:]):
        mini_route = working_route[start_idx:end_idx + 1]
        # 原代码中 random.random() 不会触发 ZeroDivisionError,直接判断即可
        if random.random() != 0:
            mini_routes.append(mini_route)
    # 处理最后一段路线
    last_start = depot_indices[-1]
    mini_routes.append(working_route[last_start:])
    
    # 输出结果
    print(f"Total number of valid miniRoutes is {len(mini_routes)}")
    print("All mini routes: ")
    for i, mr in enumerate(mini_routes, 1):
        print(f"#{i}\t{mr}")

if __name__ == "__main__":
    global_depots = list(range(50, 66))
    route = [51, 5, 33, 39, 34, 32, 64, 53, 62, 66, 58, 59, 54, 38, 9, 21, 29, 2, 61, 11, 50, 16, 20, 28, 31, 8, 26, 43, 7, 1, 27, 60, 55, 52, 10, 30, 49, 46, 12, 15, 44, 45, 37, 56, 65, 63, 42, 19, 40, 41, 13, 25, 14, 18, 57, 48, 23, 24, 6, 3, 36, 35, 22, 17, 4, 47]
    split_route(route, global_depots)

优化说明

  • 避免修改原输入:使用route.copy()复制路线,防止原列表被意外修改
  • 提升效率:将depots转为集合,成员判断时间复杂度从O(n)降至O(1)
  • 索引收集更简洁:用列表推导式一次性收集所有depot的索引,替代循环调用index()(原方法遇到重复depot会出错,优化后支持重复场景)
  • 遍历方式更直观:用zip配对连续的索引对,替代原代码中依赖try-except处理索引越界的写法
  • 修正逻辑问题:原代码中random.random()永远不会触发ZeroDivisionError,直接判断值是否为0更合理
  • 命名规范:采用符合PEP8的变量与函数命名,提升代码可读性
  • 函数解耦:将depots作为参数传入函数,避免依赖全局变量,提升函数复用性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 20:57:29