Hacker News new | ask | show | jobs
by danio 5700 days ago
Is there much benefit to

    fact = lambda n: _if (n <= 1) (1) (lambda: n * fact(n-1))
over

    def fact(n):
        if (n <= 1):
            return 1
        else:
            return n * fact(n-1)
1 line vs 5 lines doesn't seem like an advantage to me when it takes pretty much the same amount of time to read and understand the complicated 1 liner.

Is there more optimisation possible?

4 comments

     python -c "import _if; fact = lambda n: _if (n <= 1) (1) (lambda: n * fact(n-1)) ; fact(5)"
The main advantage of a 1-liner is that you can compose the whole thing and execute it without having to format anything. That is a nice feature for code that is only ever intended to be used once, such as from the python repl or some other shell. --Or more than once, for the duration of a session. It's a lot easier to use command history to get and modify a 1-liner than to replay a 5-line function definition.

When the code is primarily expressions, it's relatively easy to to this. Trying to do one-liners with regular python syntax can get tricky.

Also, if you have a series of similar relationships to present, it's often easier to line them up next to each other. You might cut 12 lines to 6 lines and the whole thing will be far clearer. Although in those cases, it's probably more effective to use a dictionary to achieve the same thing, with the advantage of data/logic separation.

    fact = lambda n: 1 if n <= 1 else n*fact(n-1)
or, for that matter:

    def fact(n): return 1 if n <= 1 else n*fact(n-1)
The point was to demonstrate that the one-liner fits easily as an argument to 'python -c' from the command-line. You could also point out "import _if;" probably won't let me call "_if()", but again that wasn't really the point.

Also, you'll need to know the version of python:

    $ python
    Python 2.4.3 (#1, Dec 11 2006, 11:39:03)
    [GCC 4.1.1 20061130 (Red Hat 4.1.1-43)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> fact = lambda n: 1 if n <= 1 else n*fact(n-1)
      File "<stdin>", line 1
        fact = lambda n: 1 if n <= 1 else n*fact(n-1)
                            ^
    SyntaxError: invalid syntax
    >>>
I understand you just copied the same snippet for your example. I'm just pointing out that Python does support that kind of if natively, so that people won't think that it doesn't.
Sometimes I put short ifs in one line, just personal taste

    def fact(n):
        if n<=1: return 1
        else:    return n * fact(n-1)
One of those times when I hugely miss languages with pattern matching/guards.

  fact(1) = 1
  fact(n) = n * fact(n-1)
Seems much more readable to me.
Which I guess can be written like

   def fact(n):
        return 1 if n<=1 else n*fact(n-1)
unfortunately not on python 2.4, which is the version we have on our production servers (2 yr old Linux)
One liner

    def fact(n): return n*fact(n-1) if n>1 else 1
They are of broadly equivalent complexity (if you are used to Python) and you can fit more of the former in an editor window.

I don't like tho' that "lambda" is a keyword in Python, I much prefer Haskell's \ or OCaml's fun.

   from math import factorial
Or

   fact = lambda n: reduce(operator.mul, xrange(1, n+1), 1)