【问题标题】:Getting all recursion results in a list在列表中获取所有递归结果
【发布时间】:2019-10-15 07:29:42
【问题描述】:

我正在学习 python 递归。为了练习,我正在给一个任务来查找列表的所有子集。例如函数:

subset([1,2)] should return [[1,2],[1],[2],[]]

我可以在递归的帮助下让我的函数打印这些结果

def subset(List):
   print(List)
   n = len(List)
   if n > 2:
      for i in range(n):
         subset(List[:i]+List[i+1:])

   if n == 2:
      subset([List[0]])
      subset([List[1]])
   if n == 1:
      subset([])
pass

L = [1,2]
test = subset(L)

打印语句打印:

[1, 2], [1], [], [2], []

我希望拥有不打印的功能,而是将其返回到所需结果给出的列表中。

我希望你能接受。

【问题讨论】:

    标签: python list recursion


    【解决方案1】:

    首先,如果您实际上不必自己实现它,标准库is happy to help

    但这对于研究递归来说是一个有趣的问题,所以让我们仔细看看。

    类似于here,对于递归的复杂用途,a) 一次进行多个递归调用,b) 需要以某种方式“累积”结果,我的建议是编写一个递归生成器。你可以机械地转换它:

    • print替换为yield

    • yield from 递归调用(正如我在另一个答案中指出的那样,对于不需要累积结果的情况,您通常需要return 这些)。

    然后从递归之外,您可以将结果收集到list,或直接对其进行迭代。

    但是,您的算法也存在一个问题:缺少两个或多个原始元素的结果将出现不止一次(如您所见),因为它们的递归“路径”不止一个.你想要的算法是:

    • 递归获取不包含第一个元素的子集
    • 对于每一个,发出两个结果:一个带有前置第一个元素,一个没有前置

    因此,我们将迭代结果,进行一些修改,而不是 yield from,然后在该循​​环中使用 yield

    将所有这些放在一起,它看起来像:

    def power_set(items):
        if not items: # empty set; base case for recursion.
            yield items
            return
        # Pull off the first element,
        first, *rest = items
        # then iterate over the recursive results on the rest of the elements.
        for without_first in power_set(rest):
            yield [first] + without_first
            yield without_first
    
    # let's test it:
    list(power_set([1,2,3]))
    # [[1, 2, 3], [2, 3], [1, 3], [3], [1, 2], [2], [1], []]
    # Good, just what we want - with no duplicates.
    

    【讨论】:

    • 这绝对是美丽的。感谢您花时间帮助我
    猜你喜欢
    • 2016-08-25
    • 1970-01-01
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 2011-11-26
    • 2013-08-13
    • 1970-01-01
    • 2021-07-27
    相关资源
    最近更新 更多