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

如何优化Python中按指定索引获取对应排列项的自定义Permutation函数

笛卡尔积索引取项函数优化方案

你当前实现的逻辑本质是从多个列表的笛卡尔积中,按指定索引直接取出对应项,无需生成全量笛卡尔积结果,下面是可行的优化方案:


优化点1:提前做边界合法性校验

先计算所有子列表长度的乘积得到总可选结果数,输入index大于等于总数时直接抛出明确的ValueError,避免后续逻辑触发无意义的索引越界异常,错误提示更友好。

优化点2:重构索引计算逻辑,去掉冗余的初始化+进位流程

原来的「先初始化索引列表再从后往前进位」的逻辑可以直接替换为权重除法逻辑,更直观简洁:

  • 从第一个子列表开始,计算当前位的权重 = 后续所有子列表的长度乘积
  • 当前位的索引 = 剩余索引值 // 权重
  • 剩余索引值 = 剩余索引值 % 权重
  • 依次遍历所有子列表即可得到所有位置的索引

优化点3:移除冗余变量,简化代码结构

原来单独存储的lengths列表、迭代计数器it都可以直接移除,减少不必要的内存占用和代码冗余。

优化点4:修改输出逻辑提升复用性

把函数直接打印结果的逻辑改为返回结果列表,需要打印时可在调用侧处理,函数可以被其他业务逻辑直接复用。


基础优化版代码
def get_cartesian_item(slots, index):
    # 边界校验
    total = 1
    for s in slots:
        total *= len(s)
    if index < 0 or index >= total:
        raise ValueError(f"索引超出范围,有效索引区间为0~{total-1}")
    
    remaining = index
    result = []
    for i in range(len(slots)):
        # 计算当前位权重
        weight = 1
        for j in range(i+1, len(slots)):
            weight *= len(slots[j])
        # 计算当前位取值
        current_idx = remaining // weight
        result.append(slots[i][current_idx])
        remaining = remaining % weight
    return result
高性能优化版(适合子列表数量多的场景)

如果嵌套列表层数很多,可以预计算后缀权重数组,把时间复杂度从O(n²)降到O(n):

def get_cartesian_item_high_perf(slots, index):
    n = len(slots)
    # 预计算后缀权重数组:suffix_weights[i]为第i位之后所有子列表的长度乘积
    suffix_weights = [1] * n
    for i in range(n-2, -1, -1):
        suffix_weights[i] = suffix_weights[i+1] * len(slots[i+1])
    
    # 边界校验
    total = suffix_weights[0] * len(slots[0])
    if index < 0 or index >= total:
        raise ValueError(f"索引超出范围,有效索引区间为0~{total-1}")
    
    remaining = index
    result = []
    for i in range(n):
        current_idx = remaining // suffix_weights[i]
        result.append(slots[i][current_idx])
        remaining = remaining % suffix_weights[i]
    return result

测试验证

和你提供的原函数输出完全一致:

l = [[0, 1, 2], [0, 1, 2], [0, 1, 2]]
print(get_cartesian_item(l, 26)) # 输出:[2, 2, 2]
print(get_cartesian_item(l, 17)) # 输出:[1, 2, 2]
print(get_cartesian_item(l, 4)) # 输出:[0, 1, 1]
get_cartesian_item(l, 27) # 抛出ValueError: 索引超出范围,有效索引区间为0~26

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:06:00