Python3不使用itertools实现二维矩阵跨子列表的全组合生成
手动实现多列表全组合(无itertools依赖)
你要实现的逻辑本质是多列表的笛卡尔积,由于输入二维数组的子列表数量不固定,硬写固定层数的嵌套循环不仅适配性差,还很容易出现逻辑错位。你之前的代码输出不对,核心问题是没有做组合状态的累积拼接,反复向同一个列表对象追加元素,才会出现输出长度不对、元素重复的问题。
实现逻辑
全程用可适配任意子列表数量的循环完成,不需要硬写多层嵌套:
- 初始化组合集合为空:还没处理任何子列表时,初始组合就是空列表组成的集合
[[]] - 逐个处理二维数组里的每一个子列表:把上一步已经生成的所有中间组合,和当前子列表的每一个元素做拼接,生成这一轮对应的全新组合集合
- 所有子列表处理完成后,得到的结果就是全部的全组合项
完整可运行代码
def get_full_combinations(input_arr): res = [[]] for sub_list in input_arr: round_res = [] # 遍历之前已生成的所有组合,和当前子列表的元素拼接 for exist_combo in res: for elem in sub_list: round_res.append(exist_combo + [elem]) res = round_res return res # 测试示例 if __name__ == "__main__": test_arr = [[1,2,3], [4,5,6], [7,8,9]] print(get_full_combinations(test_arr))
运行后输出的结果完全匹配你预期的格式:
[[1, 4, 7], [1, 4, 8], [1, 4, 9], [1, 5, 7], [1, 5, 8], [1, 5, 9], [1, 6, 7], [1, 6, 8], [1, 6, 9], [2, 4, 7], ..., [3, 6, 9]]
场景适配说明
这个写法不需要根据输入的子列表数量修改代码:不管输入的二维数组是2个、5个还是10个子列表,循环都会自动跟随子列表的数量逐次处理,和itertools.product的实现逻辑完全一致,且没有引入任何额外模块。
原代码问题拆解
你之前的代码逻辑错位主要出在两处:
- 把
res = [i]的初始化放在了遍历非首项子列表的循环内部,每碰到一个子列表就把组合重置为只包含首元素的状态,没有保留之前已经生成的拼接结果 - 循环没有按照“每一个已有的旧组合 + 每一个当前元素”的规则生成新组合,反而把当前子列表的所有元素连续追加到同一个res上,最终就输出了元素重复、长度不符合要求的错误结果。
内容的提问来源于stack exchange,提问作者ejouny
相关产品推荐
相关产品推荐

