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

Python保持列表顺序拆分为n个非空桶的所有组合实现方法

问题解决方案

核心原理

这个问题属于有序序列的k路连续拆分问题,核心思路是隔板法:

  • 长度为m的列表共有m-1个元素间隙
  • 要拆分为n个非空连续子列表,只需在m-1个间隙中选出n-1个位置插入隔板即可
  • 总共有C(m-1, n-1)种合法拆分组合,完全匹配你给出的示例场景

Python实现代码

基于标准库的简洁实现(推荐)

直接用itertools.combinations生成隔板位置组合,代码量少且高效:

import itertools

def split_list_into_buckets(lst: list, bucket_num: int) -> list:
    m = len(lst)
    # 边界校验:桶数非法时直接返回空列表
    if bucket_num <= 0 or bucket_num > m:
        return []
    # 生成所有隔板位置组合:在m-1个间隙中选bucket_num-1个位置
    split_points_list = itertools.combinations(range(1, m), bucket_num-1)
    result = []
    for split_points in split_points_list:
        # 补充前后边界方便切片
        boundaries = [0] + list(split_points) + [m]
        buckets = [lst[boundaries[i]: boundaries[i+1]] for i in range(bucket_num)]
        result.append(buckets)
    return result

# 测试用例
if __name__ == "__main__":
    lst = [1,2,3,4,5,6,7,8,9,10]
    n = 3
    res = split_list_into_buckets(lst, n)
    for item in res:
        print(item)

无依赖递归实现

如果不想依赖标准库,可以用递归回溯的方式生成所有拆分:

def split_list_recursive(lst: list, bucket_num: int) -> list:
    m = len(lst)
    if bucket_num == 1:
        return [[lst]]
    result = []
    # 第一个桶最少1个元素,最多留bucket_num-1个元素给剩下的桶
    for first_bucket_len in range(1, m - (bucket_num - 1) + 1):
        first_bucket = lst[:first_bucket_len]
        rest_buckets_list = split_list_recursive(lst[first_bucket_len:], bucket_num - 1)
        for rest_buckets in rest_buckets_list:
            result.append([first_bucket] + rest_buckets)
    return result

效果验证

以你给出的n=3测试场景为例,运行代码后输出的结果完全匹配示例:

第一个组合:[[1], [2], [3,4,5,6,7,8,9,10]]
第二个组合:[[1], [2,3], [4,5,6,7,8,9,10]]
...
最后一个组合:[[1,2,3,4,5,6,7,8], [9], [10]]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 01:21:02