Attempting to generate Pascal's Triangle as a tuple using recursion

怎甘沉沦 提交于 2019-12-08 11:17:22

问题


I need to write a function 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))

I can generate it as a list with the following function:

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

And I've tried changing this to a tuple:

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

but it doesn't work and I get the error len(last_row)-1 type int has no len.

I'm not sure how to fix this code and would appreciate any help.


回答1:


I think the problem is the result = result + new_row line.

If you want to see why, mouseover below...

result is a tuple of tuples, new_row is a tuple of numbers. If you add a tuple of numbers to a tuple of tuples, you end with a tuple of tuples and numbers! Such as ((1,), 1) which is not what you want. fix it by doing result = result + (new_row,)




回答2:


In your first code, simply add this line before the return in order to convert the list of lists to tuple of tuples:

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



回答3:


NOTE

Don't turn this in for homework. Your teacher will (correctly) gather that you cribbed it from the net. Primarily for learning purposes in terms of how compact this can be, i.e. how a professional Python programmer might write this.

So here it is, the short 8 line version:

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))

In this case, the part that was missing from your code is the spread operator. What it does is unpack that tuple of tuples from the recursive call to which you tack on the next row.

This is pretty dense, so lets unpack it a little:

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

This works because of how zip deals with lists of different lengths. For example, if the last row was (1,3,3,1) then we'd get zip((1,3,3,1),(3,3,1)) which would be ((1,3), (3,3), (3,1)). Then we add the digits in the pairs in the comprehension and get (4,6,4). Tack on the ones and there's the next row.



来源:https://stackoverflow.com/questions/42906045/attempting-to-generate-pascals-triangle-as-a-tuple-using-recursion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!