【问题标题】:Attempting to generate Pascal's Triangle as a tuple using recursion尝试使用递归将 Pascal 的三角形生成为元组
【发布时间】:2017-08-11 21:00:37
【问题描述】:

我需要编写一个函数来使用递归将 Pascal 的三角形生成为元组。

e.g pascal(5)   
((1,), (1, 1), (1, 2, 1), (1, 3, 3, 1), (1, 4, 6, 4, 1))

我可以使用以下函数将其生成为列表:

def triangle(n):
    if n == 0:
        return []
    elif n == 1:
        return [[1]]
    else:
        new_row = [1]
        result = triangle(n-1)
        last_row = result[-1]
        for i in range(len(last_row)-1):
            new_row.append(last_row[i] + last_row[i+1])
        new_row += [1]
        result.append(new_row)
    return result

我已经尝试将其更改为元组:

def pascal(n):
    if n==0:
        return ()
    elif n==1:
        return ((1,),)
    else:
        new_row = (1,)
        result = pascal(n-1)
        last_row = result[-1]
        print(last_row)
        for i in range(len(last_row)-1):
            new_row = new_row+last_row[i]+last_row[i+1]
        new_row = new_row +(1,)
        result=result+(new_row,)
    return result

但它不起作用,我收到错误len(last_row)-1 type int has no len

我不确定如何修复此代码,如果有任何帮助,我将不胜感激。

【问题讨论】:

  • 当您printlast_row 时,您在输出中看到了什么?因为它不是元组...(提示提示)
  • @JaredSmith,是的,我意识到了这一点,但不确定如何修复代码。

标签: python list recursion tuples pascals-triangle


【解决方案1】:

我认为问题出在result = result + new_row 行。

如果您想了解原因,请将鼠标悬停在下方...

result 是一个元组的元组,new_row 是一个数字的元组。如果您将一个数字元组添加到一个元组元组中,那么您将以一个元组 个数字的元组结束!比如((1,), 1) 这不是你想要的。 通过result = result + (new_row,)修复它

【讨论】:

  • 修复此问题后,我得到一个新的错误行:new_row = new_row + last_row[i] + last_row[i+1] 只能将元组(不是“int”)连接到元组但是如果我改变它到:new_row = new_row+(last_row[i],)+(last_row[i+1],) 输出完全不同
  • 这是一个不同的问题:-)。你应该能够解决它。 new_row 是一个整数元组,last_row 是一个整数元组,那么该行试图做什么..?错误信息非常有用!
  • 好的,那么(last_row[i],)+(last_row[i+1],) 给了你什么?你希望它给你什么?
  • last_row[i] 是第一个元素,last_row[i+1] 是第二个元素,即两个数字,是的,但是(last_row[i],) 是一个包含数字的元组,所以(last_row[i],) + (last_row[i+1],) 是一个元组加上一个tuple,它给你另一个元组(例如(1,) + (2,) = (1, 2),但你想要最后两个元素的总和,对吧..?
  • 我想通了 :) 感谢您的耐心和指导!
【解决方案2】:

在您的第一个代码中,只需在 return 之前添加这一行,以便将 list of lists 转换为 tuple of tuples

tuple_results = tuple(tuple(x) for x in results)
return tuple_results

【讨论】:

  • 这仅在我添加内部函数/使用另一个函数来执行此操作时才有效,因为此函数是递归函数。我想在一个功能中做到这一点。不过感谢您的意见!
  • 不,如果两行的缩进相同(就像我写的那样),它会像这样工作。
  • result.append(new_row) AttributeError: 'tuple' object has no attribute 'append'
【解决方案3】:

注意

不要把这个作为家庭作业。你的老师会(正确地)收集到你是从网上抄来的。主要是为了了解它的紧凑程度,即专业的 Python 程序员如何编写它。

就是这样,简短的 8 行版本:

def pascal(n):
    if n <= 0:
        return ()
    elif n == 1:
        return ((1,),)
    else:
        res = pascal(n - 1) # recursive call
        return (*res, (1, *[n + i for n, i in zip(res[-1], res[-1][1:])], 1))    
print(pascal(5))

在这种情况下,您的代码中缺少的部分是展开运算符。它的作用是从递归调用中解压缩元组的元组,然后在下一行添加。

这是相当密集的,所以让我们把它拆开一点:

return (*res, # open paren starts new tuple, *res unpacks the recursive call
    (1, # starts the tuple for the current row
      *[ # spread the result of the list comprehension
          n + i for n, i in # we're going to add the items in two lists
          zip( # here's where we combine the two lists to add
              res[-1], # last row of recursive call
              res[-1][1:] # same but shifted 1 index
          ),
       ], # end list comprehension
     1) # 1 to end the current row
  ) # end the total result, i.e. tuple of rows

这是因为zip 如何处理不同长度的列表。例如,如果最后一行是(1,3,3,1),那么我们将得到zip((1,3,3,1),(3,3,1)),即((1,3), (3,3), (3,1))。然后我们在理解中添加对中的数字并得到(4,6,4)。粘上那些,然后是下一行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-12
    • 2022-12-20
    • 2011-04-22
    • 1970-01-01
    • 2020-07-21
    相关资源
    最近更新 更多