如何在Python中使用递归编制两个列表

如何在Python中使用递归编制两个列表,python,list,recursion,Python,List,Recursion,我想编制两个列表并输出所有可能的结果 例如, 输入:两个列表l1=[1,2],l2=[3,4] 输出:[1,2,3,4],[1,3,2,4],[1,3,4,2],[3,1,2,4],[3,1,4,2],[3,4,1,2] 注意:我需要在每个列表中保持顺序(例如,1总是在2之前,3总是在4之前) 我解决这个问题的方法是从一个列表中删除头部,递归,然后对另一个列表执行相同的操作。代码如下: all_possibles = [] def weaveLists(first, second, added)

我想编制两个列表并输出所有可能的结果
例如,
输入:两个列表l1=[1,2],l2=[3,4]
输出:[1,2,3,4],[1,3,2,4],[1,3,4,2],[3,1,2,4],[3,1,4,2],[3,4,1,2]
注意:我需要在每个列表中保持顺序(例如,1总是在2之前,3总是在4之前)

我解决这个问题的方法是从一个列表中删除头部,递归,然后对另一个列表执行相同的操作。代码如下:

all_possibles = []
def weaveLists(first, second, added):
    if len(first) == 0 or len(second) == 0:
        res = added[:]
        res += first[:]
        res += second[:]
        all_possibles.append(res)
        return

    cur1 = first[0]
    added.append(cur1)
    first = first[1:]
    weaveLists(first, second, added)
    added = added[:-1]
    first = [cur1] + first

    cur2 = second[0]
    added.append(cur2)
    second = second[1:]
    weaveLists(first, second, added)
    added = added[:-1]
    second = [cur2] + second


weaveLists([1, 2], [3, 4], [])
print(all_possibles)
我得到的结果是: [1,2,3,4],[1,3,2,4],[1,3,4,2],[1,3,1,2,4],[1,3,1,4,2],[1,3,1,4,1,2]]

我不明白为什么在最后三个列表中,第一个列表的标题1没有被删除


有人能帮忙吗?谢谢

还有另一种方法:我们生成编织列表中第一个列表项的可能索引,并相应地填充列表

我们可以使用
itertools.compositions
生成索引:它是编织列表的索引的组合,每次取其中的len(第一个列表)

from itertools import combinations
​
def weave(l1, l2):
    total_length = len(l1) + len(l2)
    # indices at which to put items from l1 in the weaved output
    for indices in combinations(range(total_length), r=len(l1)):
        out = []
        it1 = iter(l1)
        it2 = iter(l2)
        for i in range(total_length):
            if i in indices:
                out.append(next(it1))
            else:
                out.append(next(it2))
        yield out
样本运行:

l1 = [1, 2]
l2 = [3, 4]
​
for w in weave(l1, l2):
    print(w)
    
​
[1, 2, 3, 4]
[1, 3, 2, 4]
[1, 3, 4, 2]
[3, 1, 2, 4]
[3, 1, 4, 2]
[3, 4, 1, 2]
另一个具有较长列表的示例运行:

l1 = [1, 2]
l2 = [3, 4, 5]
​
for w in weave(l1, l2):
    print(w)
    
​
[1, 2, 3, 4, 5]
[1, 3, 2, 4, 5]
[1, 3, 4, 2, 5]
[1, 3, 4, 5, 2]
[3, 1, 2, 4, 5]
[3, 1, 4, 2, 5]
[3, 1, 4, 5, 2]
[3, 4, 1, 2, 5]
[3, 4, 1, 5, 2]
[3, 4, 5, 1, 2]

您得到这些意外结果的原因是您在此处变异添加了:

added.append(cur1)
…这将影响调用者的
添加的
列表(无意中)。“撤消”操作不会改变列表:

added = added[:-1]
这将创建一个新列表,因此此“撤消”操作不会回滚调用者列表中的更改

简单的解决方法是将对
append
的调用替换为:

added = added + [cur1]
同样的情况也会发生在第二个街区

如果您动态传递递归调用的新值,并用以下代码块替换这两个代码块,则更容易:

weaveLists(first[1:], second, added + [first[0]])
weaveLists(first, second[1:], added + [second[0]])

你一定要使用递归吗?这似乎没必要,谢谢@Marat。你是对的。我不一定要使用递归。但我正在努力弄明白为什么这个递归不起作用。谢谢,@thierrylahuille。这绝对有效,是一个很好的解决方案!你能帮我识别我原始递归代码中的错误吗?