andrew cooke wrote:
Terry Reedy wrote:
Reverse the test order

def fact(n):
     if n > 0: return fact(n-1)*n
     if n == 0: return 1
     raise ValueError

sweet!  but is this generally possible?

I believe so, for some meaning of 'generally'.

> ie: did you think this up for
this question or is it an idiom that you find yourself using often?

It is an idiom I developed for an algorithm book-in-progress that will include detailed comparisons of 'body' recursive (my term for 'not tail recursive", such as fact() above), tail recursive, and iterative versions of algorithms.

Here are written-for-didactic-purposes tail and iterative versions of fact that are computationally equivalent to the above in that they compute the same expression, (...((1*1)*2)*....*n), without commutative or associative transformation, and raise the same error (expanded).

def fact_tail(n, i=0, res=1):
    if i < n: return fact_tail(n, i+1, res*(i+1))
    if i == n: return res
    raise ValueError("Input negative or non-integral")

def fact_iter(n, i=0, res=1):
    while i < n: i,res = i+1, res*(i+1)
    if i == n: return res
    raise ValueError("Input negative or non-integral")

My original reason for writing the tail recursion in the same reversed order was to make the conversion to iteration as obvious as possible. But I them noticed that it also made possible 'test once for bad input without a separate function."

Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to