尝试使用递归生成Pascal的三角形作为元组

时间:2017-03-20 14:20:49

标签: python list recursion tuples pascals-triangle

我需要编写一个函数来使用递归生成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

我不确定如何修复此代码,并感谢任何帮助。

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

我认为问题是result = result + new_row行。

如果你想知道为什么,请将鼠标放在...

之下
  

result是一个元组元组,new_row是一个数字元组。如果你向一个元组元组添加一个数字元组,你会得到元组数字的元组!比如((1,), 1)这不是你想要的。  通过result = result + (new_row,)

来修复它

答案 2 :(得分:0)

请勿将其转入作业。你的老师会(正确地)收集你从网上抄下来的东西。主要是为了学习目的,这可能是多么紧凑,即专业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)。抓住那些,然后是下一行。