python通过递归函数获取所有子集

问题描述

我编写了一些python代码来通过递归获取所有子集。

如果给定数据

data = [1,2,3,4,5]
length = 3

结果将以 3 个长度打印所有子集 像这样

1,3
1,4
1,5
2,4
2,5...

这是我的代码

data = [1,5]
n = 5
r = 3 
    templist = []
    def re(max,length,idx):
        if idx == max:
            return
        if idx == length:
            for i in templist:
                print(" "+str(i))
            print("\n")
            return
        else:
            templist.append(data[idx])
            re(max,idx+1)
            templist.pop()
            re(max,idx+1)
    if __name__ == "__main__":
     re(n,r,0)

我期望它循环所有可能的子集 但是当它遇到调用时它会失败 re(max,idx+1)temlist.pop()

当代码进入第二个re()函数时 我希望它附加 templist.append(data[4]) 因为第一个 re() 函数通过 if 条件返回 if idx == length:

idx 为 3 时,idx 与 length(3) 相同。 所以递归结束,运行 temlist.pop() 和 它将进入第二个 re(4) 函数 因为我编码了 idx+1

但它会失败 idx 只在 2~3 之间圈起来

所以我改变了第二个递归函数

re(max,idx+1)

re(max,idx+2)

我彻底崩溃了。

我认为我的逻辑基本上是错误的。 但我不知道在哪里修复它我该如何解决按预期调用递归?

解决方法

方法如下:

def func(data,length,lst=[]):
    for i in data[length - 1:]:
        lst.append(data[:length - 1] + [i])
    if data:
        func(data[1:],lst)
    return lst

data = [1,2,3,4,5]
length = 3

print(func(data,length))

输出:

[[1,3],[1,4],5],[2,[3,5]]

说明:

  1. 定义一个接受三个参数的函数,列表(data)、长度(length)和一个空列表 (lst) 用于存储输出值 (在函数之外定义它被认为是不好的做法)

  2. 遍历除第一个 data 索引元素之外的 length - 1 列表元素,并将 0 索引中的元素附加到 length - 1 索引加上迭代的当前元素。

  3. 如果 data 列表没有变空,则再次调用当前函数,但使用切片 [1:] 删除第一个字符。

  4. 如果 data 列表没有变空,则返回 lst 列表。


您的另一个选择是使用 Python 强大的生成器。使用这种技术,我们不再需要 lst 参数 -

def func(data,length):
    for i in data[length - 1:]:
        yield data[:length - 1] + [i]
    if data:
        yield from func(data[1:],length)

现在我们可以使用迭代检索排列 -

data = [1,5]
length = 3

for perm in func(data,length):
  print(perm)
[1,3]
[1,4]
[1,5]
[2,4]
[2,5]
[3,5]

或者我们可以在 list -

中收集所有排列
data = [1,5]
length = 3

print(list(func(data,length)))
[[1,5]]
,

最好的方法是使用 itertools 的内置排列。

from itertools import permutations
data = [1,5]
length = 3
res = list(permutations(data,length))

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...