En Tue, 10 Feb 2009 23:58:07 -0200, Steven D'Aprano <ste...@remove.this.cybersource.com.au> escribió:

I sometimes write recursive functions like this simple factorial:


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

At the risk of premature optimization, I wonder if there is an idiom for
avoiding the unnecessary test for n <= 0 in the subsequent recursive
calls? For the sake of the argument, let's pretend the test is expensive
and I have a good reason for wanting to avoid it on subsequent calls :)



I've done this:

def _fact(n):
    if n = 0: return 1
    return _fact(n-1)*n

def fact(n):
    if n < 0: raise ValueError
    return _fact(n)

but that's ugly. What else can I do?

I don't think it's ugly; you have an implementation (_fact) and its public interfase (fact). In 'fact' you could check that n is actually an integer (an implicit precondition, your algorithm doesn't finish in other case) and whatever validation is also required. Perhaps its arguments come from user input and you need stricter tests, or convert from other type (like float->int). On the other hand, '_fact' is private and you can assume their arguments are exactly what you require. In Pascal I would have used a nested _fact function; in Python it isn't as efficient so I'd write it as your own example.

This is a rather used idiom - in the Python C API, by example, usually you see a public function PyFoo_DoSomething(PyObject* obj) and a private one _PyFoo_DoSomething(double x) (assume a function like sqrt, number -> float). The public one takes a generic Python object, checks its type, converts it to a C "double" value, and if all went OK, finally calls the private implementation passing that value.

--
Gabriel Genellina

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

Reply via email to