【问题标题】:python get all subset by recursive functionpython通过递归函数获取所有子集
【发布时间】:2020-12-25 13:09:34
【问题描述】:

我编写了一些 python 代码以递归方式获取所有子集。

如果给定数据

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

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

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

这是我的代码

data = [1,2,3,4,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,length,idx+1)
            templist.pop()
            re(max,length,idx+1)
    if __name__ == "__main__":
     re(n,r,0)

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

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

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

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

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

re(max,length,idx+1)

到

re(max,length,idx+2)

我彻底崩溃了。

我认为我提出的逻辑大错特错。 但我不知道在哪里解决它如何解决我所期望的调用递归?

【问题讨论】:

标签: python algorithm recursion subset tail-recursion


【解决方案1】:

方法如下:

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

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

print(func(data, length))

输出:

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

解释:

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

  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,2,3,4,5]
length = 3

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

或者我们可以在list 中收集所有排列 -

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 嘿,很好的答案!不幸的是,这并没有达到 OP 所描述的效果。
    猜你喜欢
    • 2021-02-25
    • 2011-01-24
    • 2014-12-07
    • 2022-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多