尝试使用递归将帕斯卡三角生成为元组
Attempting to generate Pascal's Triangle as a tuple using recursion
我需要编写一个函数来使用递归将帕斯卡三角生成为元组。
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
。
我不确定如何修复此代码,如有任何帮助,我将不胜感激。
在您的第一个代码中,只需在 return
之前添加此行即可将 list of lists
转换为 tuple of tuples
:
tuple_results = tuple(tuple(x) for x in results)
return tuple_results
我认为问题出在 result = result + new_row
行。
如果您想了解原因,请将鼠标悬停在下方...
result
是元组的元组,new_row
是数字的元组。如果您将数字元组添加到元组元组,您将以元组 and 数字结束!例如 ((1,), 1)
这不是你想要的。
通过 result = result + (new_row,)
修复它
注意
不要把它交作业。你的老师会(正确地)认为你是从网上抄袭的。主要是为了学习它的紧凑程度,即专业 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)
。处理那些,然后是下一行。
我需要编写一个函数来使用递归将帕斯卡三角生成为元组。
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
。
我不确定如何修复此代码,如有任何帮助,我将不胜感激。
在您的第一个代码中,只需在 return
之前添加此行即可将 list of lists
转换为 tuple of tuples
:
tuple_results = tuple(tuple(x) for x in results)
return tuple_results
我认为问题出在 result = result + new_row
行。
如果您想了解原因,请将鼠标悬停在下方...
修复它
result
是元组的元组,new_row
是数字的元组。如果您将数字元组添加到元组元组,您将以元组 and 数字结束!例如((1,), 1)
这不是你想要的。 通过result = result + (new_row,)
注意
不要把它交作业。你的老师会(正确地)认为你是从网上抄袭的。主要是为了学习它的紧凑程度,即专业 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)
。处理那些,然后是下一行。