Thursday, June 30, 2011

Factorial Function One-Liner in Python

I recently got a copy of the Python Cookbook. This is the first programming book I've picked up that one would call "advanced." That is, it assumes you know what an if-statement does. As a result, the book is rather refreshing.

I picked this book up because I've been looking for a solid place to read code, something I've heard advocated frequently among more experienced hackers. The book is full of code examples and explanations, and seeing how other hackers solved particular problems makes it clear why reading code is so crucial to coding better. In nearly every piece of code I've read through, I've encountered something new. My favorite so far is 17.9: Computing Factorials with lambda:
    f = lambda n: n-1 + abs(n-1) and f(n-1)*n or 1

So, this is the factorial function, contained entirely on a single line. A few subtleties of Python allow it to work, which the book explains quite well.

First of all, when a lambda form is defined, it isn't evaluated. This allows lambda forms to be defined recursively. Generally, lambda forms are not assigned names--they're "anonymous functions"--but they can be, as was done here.

The other trick--and the part that wasn't obvious to me--was the use of the ternary operator, which I'd never heard of before this. In C, there's a statement with the syntax:
    condition?iftrue:iffalse

So, effectively, this can be thought of as "Is condition true? Do iftrue. If it is false, do iffalse." In Python, the syntax is:
    condition and iftrue or iffalse

This allows you to write one line if statements. Combined with lambda, you can write one line recursive functions this way, where condition is your continue/escape condition.

Consider, also, the condition. It's not an explicit boolean statement. However, Python has implicit boolean evaluations. For example, an empty list "[]" evaluates as false. Similarly, "0" evaluates to false.

If you're doing anything more sophisticated, this is rather pointless. However, if you need merely choose between a base case or recurring, this is a simple, concise way to do it.

0 Comments:

Post a Comment

<< Home

-->