Staying as close as possible from your initial try, I would do something that also returns a sequence, not a number
def sequence(N, x0, r):
A=[x0]
if N==0:
return A
else:
return A + sequence(N-1, r*x0*(1-x0), r)
print(sequence(10, 2, 2))
Explanation: it computes the first element of the sequence, and then the rest of it, recursively.
Just trace it for a few values.
For N=0
Simple, it just returns [x0]
For N=1
For clarity (otherwise, x0 means different things during recursions), let's choose x0 for the initial call=2, and also (even if r stays the same thorough all call), choose r=3. So let's call sequence(1,2,3)
- In
sequence(1,2,3) call, we starts by A=[2]
- Then, since N≠0, we go to else, so we compute
A=[2]+sequence(0,3*2*(1-2),3) recursively, that is sequence(0,-6,3)``
- In this
sequence(0,-6,3) call, we starts with A=[-6]
- Since N=0 in this call, we simply return A, aka
[-6]
- So, back in
sequence(1,2,3), we return A+result of recursive call sequence(0,-6,3). That is A+[-6]. That is [2]+[-6]
- so final answer is
[2, -6]
For N=2
(And still initial x0=2, and r=3)
- In
sequence(2,2,3) call, we start with A=[2]
- Since N=2≠0, we return
A+sequence(N-1,r*x0*(1-x0), r), and for that we need to compute sequence(1, -6, 3) recursively
- In
sequence(1,-6,3) call, we start with A=[-6]
- Sine N=1≠0, we return
A+sequence(N-1,r*x0*(1-x0),r) that is [-6] + sequence(0, 3*(-6)*7, 3) = [-6] + sequence(0, -126, 3).
- so we have to call recursively
sequence(0, -126, 3).
- In
sequence(0, -126, 3), we start we A=[-126]
- Since N=0, we just return that
[-126]
- now back in
sequence(1,-6,3) call. Our [-6]+sequence(0,-126,3) computation [-6]+[-126] or [-6, -126], which is what we return
- now back in
sequence(2, 2, 3) call. Our [2]+sequence(1,-6,3) computation is therefore [2]+[-6,-126] or [2,6,-126]. Which is our final answer
Note that no redundant computation is done here. And it stays as close as possible from your initial answer.
Another, more "functional" recursion, which for the record, was my previous main answer (what is now my main answer was 1st provided as an alternative solution, before I realized it was probably the one your are expected to provide)
def sequence(N, x0, r):
if N == 0:
return [x0]
else:
prev=sequence(N-1, x0, r)
prev.append(r * prev[-1] * (1-prev[-1]))
return prev
It is also recursive, and efficient. But not as elegant. I mean, the recursion here is just a way to repeat N times the prev.append(...) line. We could have achieved the same result by iterating N times that line with a for loop. So recursion brings nothing. Whereas in the first solution, it has the advantage to stick to mathematical recurrent definition of the sequence (that is one advantage of recursion. It may be harder to understand for computer scientist used to imperative programming. But for a mathematician, it is closer to the way we define sequences)
Nas-is to the recursive calls ofsequence(), so there's no way you could ever reachif N == 0if you originally pass in a non-zeroN.