【问题标题】:Unable to generate combination of numbers in python list using recursion无法使用递归在 python 列表中生成数字组合
【发布时间】:2021-04-22 00:27:51
【问题描述】:

我正在尝试使用递归在 python 列表中生成数字组合 我的代码如下

nums = [2,3,4,6]

def backtrck(temp, starting_index, nums):
    if len(temp) == 2:
        print(temp)
        return
    temp.append(nums[starting_index])
    for i in range(starting_index + 1, len(nums)):
        backtrck(temp, i, nums)

backtrck([], 0, nums)

由于某种原因,上面的代码无法生成正确的组合。

代码的目的:我想生成所有以索引0开头的数字组合,其长度应等于2

预期输出

[2, 3]
[2, 4]
[2, 6]

实际输出

[2, 3]
[2, 3]
[2, 3]
[2, 3]

我不明白这个递归出了什么问题,我希望有人能帮我解决这个问题

【问题讨论】:

  • 您应该检查代码中的几项内容。就像return 一样,您不会返回任何内容。同样正如答案中告诉您的那样,如果您需要单次迭代,则不确定使用递归的意义何在
  • 您应该使用调试器或this site 来单步调试您的代码并观察它在做什么。
  • @IgnacioAlorre return 不需要返回任何东西就可以正确使用它。函数中的return语句是停止继续解析循环。
  • 如果您在使用 IDE现在是学习其调试功能或内置 Python debugger 的好时机。在程序中的关键点打印 stuff 可以帮助您跟踪正在发生或未发生的事情。 What is a debugger and how can it help me diagnose problems?

标签: python recursion


【解决方案1】:

当你可以简单地使用for循环时,递归是不必要的:

nums = [2,3,4,6]

def backtrck(starting_index, nums):
    start = nums[starting_index]
    for num in nums[starting_index + 1:]:
        print([start, num])
        
backtrck(0, nums)

输出:

[2, 3]
[2, 4]
[2, 6]

其中切片 nums[start_index + 1:] 返回从 starting_index 之后的一个索引开始的 nums 列表中所有元素的列表。

更新

既然您已经指出在您的代码中递归是必要的,只需将 backtrck(temp, i, nums) 递归调用替换为 backtrck(i, nums, [temp[0], nums[i]]) 以保留列表的起始索引:

nums = [2, 3, 4, 6]

def backtrck(starting_index, nums, temp=[]):
    if len(temp) == 2:
        print(temp)
        return
    temp.append(nums[starting_index])
    for i in range(starting_index + 1, len(nums)):
        backtrck(i, nums, [temp[0], nums[i]])

backtrck(0, nums)

输出:

[2, 3]
[2, 4]
[2, 6]

请注意,我已将位置参数 temp 更改为关键字参数。它仍然可以将temp 用作位置参数,但如果temp 列表总是以空开头。

【讨论】:

  • 感谢您的替代方法。但是我提出的问题是一个更大的问题的一部分,该问题专门要求以递归方式解决。这就是我要求递归方法的原因
  • 你当然让它递归,但它有点棘手。 :)
【解决方案2】:

你的函数有什么问题:

经过几次递归调用 temp 变为 [2,3] 然后在下一次递归中满足基本情况 (len(temp) == 2:) 并且该函数实例返回而不添加任何内容。下一个 for 循环迭代 recurses 会发生同样的事情。一旦temp[2,3],它就永远不会改变。

如何解决:

您的函数结构存在许多问题,这不是简单的单行修复。你需要弄清楚如何

  • 满足基本情况时
    • 捕获(或打印)temp
    • 返回对前一个函数有意义的东西,它可以用来继续进行组合
  • 函数需要对递归调用的返回值进行操作
  • 在递归过程/进程中添加 for 循环会使事情变得复杂,也许想办法不使用它。

我会从函数开始。我不知道您是否要求某人给您一个全新的功能,因此我将搜索有关查找/生成列表项组合的递归解决方案的问题。


以下是一些相关的 SO 问题/答案。如果其中任何一个解决了您的问题,请告诉我们,以便我们将您的问题标记为重复。大多数没有taken two-at-a-time 约束,但也许你可以适应。还有很多。

Recursive function that returns combinations of size n chosen from list
Recursively find all combinations of list
python recursion list combinations without using generator
Using recursion to create a list combination

松散相关:
Nth Combination
Finding all possible combinations of numbers to reach a given sum
Creating all possible k combinations of n items in C++ - 不是 Python,但算法可能有用。

【讨论】:

    【解决方案3】:

    谈到递归,我的建议是保持简单,让递归为您完成工作:

    def backtrck(numbers):
        if len(numbers) < 2:
            return []
    
        first, second, *rest = numbers
    
        return [[first, second]] + backtrck([first] + rest)
    
    nums = [2, 3, 4, 6]
    
    print(*backtrck(nums), sep='\n')
    

    输出

    > python3 test.py
    [2, 3]
    [2, 4]
    [2, 6]
    >
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-03
      • 2019-04-27
      • 1970-01-01
      • 1970-01-01
      • 2019-04-22
      • 2017-03-26
      相关资源
      最近更新 更多