Software bugs aren't inevitable
Terry Reedy
tjreedy at udel.edu
Thu Sep 15 00:41:07 EDT 2005
"Steven D'Aprano" <steve at REMOVETHIScyber.com.au> wrote in message
news:pan.2005.09.14.18.39.09.585065 at REMOVETHIScyber.com.au...
> On Wed, 14 Sep 2005 14:32:17 +0200, Jerzy Karczmarczuk wrote:
>> Here you are a recursive version linear in n; it
>> returns the two last Fibonacci numbers of the sequence
The minor problem is that for n = 0, there are no two last numbers.
>> def fibo(n):
>> if n<2:
>> return (n-1,n)
>> else:
>> (a,b)=fibo(n-1)
>> return (b,a+b)
>
> Ah, I like this algorithm! I'll add it to my collection. Thank you.
The above is what I call the 'body recursive' form. Others have other
names.
Here is a version of the 'tail recursive' form (without negative input
check).
def fibt(n):
if n < 2: return n
def _fib(i, a, b):
if i < n:
return _fib(i+1, b, a+b)
return b
return _fib(2, 1, 1)
The inner function does not have to be wrapped; for n >=2, the outer
function simply passes on its final return. However, the wrapping masks
the accumulator parameters from the user and correctly sets their initial
values. It also handles the base cases more efficiently by checking for n
< 2 just once instead of every inner loop.
Here is the direct iterative equivalent:
def fibi(n):
if n < 2: return n # same as before
i, a, b = 2, 1, 1 # corresponds to initial _fib call
while i < n: # repeated ('recursive') if
i, a, b = i+1, b, a+b # corresponds to args of recursive _fib call
return b # same as before
The transformation is mechanical and is done internally by some language
interpreters. (Although some might require the inner condition reversed
and the returns switched.)
Terry J. Reedy
More information about the Python-list
mailing list