在不使用isinstance的情况下对列表中的列表进行递归处理

2 投票
4 回答
964 浏览
提问于 2025-04-16 17:34

我有一个任意的数字列表,这个列表里面又包含了一些相同类型的数字列表。其实这些数字是一些边界坐标,用来表示在一个多维空间中我想要绘制的箱子的角落,不过这不是重点。我想生成一个包含所有可能组合的列表。比如说:[[1,2], [3,4],[5,6]] 这个列表会生成 [[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,3,5]...] 这样的组合。

有没有人能帮我改进一下这段代码?我不太喜欢使用 isinstance() 这个函数,但我找不到更符合 Python 风格的方法来在第一次遍历时添加元素,特别是当第一个参数(pos)是一个数字列表而不是一个列表的列表时。

def recurse(pos, vals):
    out = []
    for p in pos:
        pl = p if isinstance(p,list) else [p]
        for x in vals[0]:
            out.append(pl + [x])
    if vals[1:]:
        return recurse(out, vals[1:])
    else:
        return out


a = [[1,2,3],[4,5,6],[7,8,9],[11,12,13]]

b = recurse(a[0], a[1:])

谢谢。

4 个回答

0

当有一个库或者模块可以完成你想要的功能时,你应该选择使用它(顺便说一句,提到itertools.product的朋友们值得点赞)。不过,如果你对实现这个功能的算法感兴趣,那么你可以了解一种叫做递归下降的算法。

answer = []
def recurse(points, curr=[]):
    if not points:
        answer.append(curr)
        curr = []
        return
    else:
        for coord in points[0]:
            recurse(points[1:], curr+[coord])
1

可以试试用 itertools.product 这个工具。

import itertools

a = [[1,2,3],[4,5,6],[7,8,9],[11,12,13]]
iterator = itertools.product(*a)
result = [item for item in iterator.next()]
6

从你的例子来看,你似乎只想要这个

from itertools import product
a = [[1,2,3],[4,5,6],[7,8,9],[11,12,13]]
print list(product(*a))

撰写回答