Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Can someone explain the concrete reasons why BDFL choose to make Python lambdas single line?

This is good:

lambda x: x**x

This results in an error:

lambda x:

I understand that making lambda multi-line would somehow "disturb" the normal indentation rules and would require adding more exceptions, but isn't that worth the benefits?

Look at JavaScript, for example. How can one live without those anonymous functions? They're indispensable. Don't Pythonistas want to get rid of having to name every multi-line function just to pass it as an argument?

share|improve this question
Considering that you note the concrete reasons why Guido doesn't allow multi-expression lambdas and then dismiss them, I'm going to assume you're seeking validation rather than a real answer. – Jason Baker Aug 7 '11 at 18:13
Apart from saving seven characters, how is this any better than a def? It now has exactly the same visual structure. – detly Aug 8 '11 at 1:28
up vote 24 down vote accepted

Guido van van Rossum answered it himself:

But such solutions often lack "Pythonicity" -- that elusive trait of a good Python feature. It's impossible to express Pythonicity as a hard constraint. Even the Zen of Python doesn't translate into a simple test of Pythonicity...

In the example above, it's easy to find the Achilles heel of the proposed solution: the double colon, while indeed syntactically unambiguous (one of the "puzzle constraints"), is completely arbitrary and doesn't resemble anything else in Python...

But I'm rejecting that too, because in the end (and this is where I admit to unintentionally misleading the submitter) I find any solution unacceptable that embeds an indentation-based block in the middle of an expression. Since I find alternative syntax for statement grouping (e.g. braces or begin/end keywords) equally unacceptable, this pretty much makes a multi-line lambda an unsolvable puzzle.

Basically, he says that although a solution is possible, it's not congruent with how Python is.

share|improve this answer
+1 thanks for the thread link -- but i would still appreciate multi-line lambdas -- they are invaluable -- look at JavaScript, PHP has them included also. – treecoder Aug 7 '11 at 17:49
@greengit You can just use a nested def. It isn't the same as anonymous functions, but they're close enough. – jsternberg Aug 7 '11 at 17:58
nested defs don't help when passing functions as arguments -- that's the number one reason why i'd like multi-line lambds – treecoder Aug 7 '11 at 18:03
@greengit - I think you're better off taking this up with GvR than posting your comments here. – Jason Baker Aug 7 '11 at 18:10
@greengit: You do know that you can pass the function in as an argument to another function? You can't write it inline, but there is no programming technique that is not available to you. – btilly Aug 7 '11 at 19:56

it's perfectly fine to do a multi line lambda in python: see

>>> f = lambda x: (
...   x**x)
>>> f
<function <lambda> at 0x7f95d8f85488>
>>> f(3)

the real lambda limitation is the fact that lambda must be a single expression; it can't contains keyword (like python2's print or return).

GvR choose to do so to limit the size of the lambda, as they normally are used as parameters. If you want a real function, use def

share|improve this answer
multi line is about the insert of the '\n' character :D python does not have multi statement lambda. You really want to use def. Think about it: you really need a callable as a parameter of your function? And the users of that function aren't allowed to pass your default callable? How can they pass it if you don't give it to them? – Vito De Tullio Aug 7 '11 at 18:14
btw, can you provide an example of your need of an anonimous function? – Vito De Tullio Aug 7 '11 at 18:19
Yeah, I find the limitation of a single expression really frustrating. True, that if they allow multi-expression lambdas people will most certainly start to abuse it but the other way around is too restrictive omho. – rbaleksandar Feb 21 at 0:05

I know this is super old, but putting here as a reference.

An alternative to using lambda could be to use a def in a non-conventional way. The goal is to pass a def to a function, which can be done in only one circumstance -- a decorator. Notice that with this implementation def result does not create a function, it creates the result of reduce(), which ends up being a dict.

Shameless plug: I do a lot of this here.

>>> xs = [('a', 1), ('b', 2), ('a', 3), ('b', 4)]
>>> foldl = lambda xs, initial: lambda f: reduce(f, xs, initial)
>>> @foldl(xs, {})
... def result(acc, (k, v)):
...     acc.setdefault(k, 0)
...     acc[k] += v
...     return acc
>>> result
{'a': 4, 'b': 6} 

Note that multi-statement lambdas can be done, but only with really, really ugly code. However, what is interesting is how scoping works with this implementation (note the multiple usage of the name variable and the shadowing of the message variable.

>>> from __future__ import print_function
>>> bind = lambda x, f=(lambda x: x): f(x)
>>> main = lambda: bind(
...     print('Enter your name.'), lambda _: bind(
...     raw_input('> '), lambda name: bind(
...     'Hello {}!'.format(name), lambda message: bind(
...     print(message), lambda _: bind(
...     'Bye {}!'.format(name), lambda message: bind(
...     print(message)
... ))))))
>>> main()
Enter your name.
> foo
Hello foo!
Bye foo!
share|improve this answer
+1 for a monadic approach – jozefg Nov 16 '13 at 13:54

Hacking together a multi-statement lambda isn't quite as bad as pyrospade makes out: sure we could compose a bunch of monadic functions using bind, like in Haskell, but since we're in the impure world of Python, we might as well use side-effects to achieve the same thing.

I cover a few ways to do this on my blog.

For example, Python guarantees to evaluate the elements of a tuple in order, so we can use , much like an imperative ;. We can replace many statements, like print, with expressions, like sys.stdout.write.

Hence the following are equivalent:

def print_in_tag_def(tag, text):
    print "<" + tag + ">"
    print text
    print "</" + tag + ">"

import sys
print_ = sys.stdout.write
print_in_tag_lambda = lambda tag, text: (print_("<" + tag + ">"),
                                         print_("</" + tag + ">"),

Note that I've added a None at the end, and extracted it using [-1]; this sets the return value explicitly. We don't have to do this, but without it we'd get a funky (None, None, None) return value, which we may or may not care about.

So we can sequence IO actions. What about local variables?

Python's = forms an statement, so we need to find an equivalent expression. One way is to mutate the contents of datastructure, passed in as an argument. For example:

def stateful_def():
    foo = 10
    bar = foo * foo
    foo = 2
    return foo + bar

stateful_lambda = (lambda state: lambda *_: (state.setdefault('foo', 10),
                                             state.setdefault('bar', state.get('foo') * state.get('foo')),
                                             state.setdefault('foo', 2),
                                             state.get('foo') + state.get('bar'))[-1])({})

There are few tricks being used in stateful_lambda:

  • The *_ argument allows our lambda to take any number of arguments. Since this allows zero arguments, we recover the calling convention of stateful_def.
    • Calling an argument _ is just a convention which says "I'm not going to use this variable"
  • We have one ("wrapper") function returning another ("main") function: lambda state: lambda *_: ...
    • Thanks to lexical scope, the argument of the first function will be in-scope for the second function
    • Accepting some arguments now and returning another function to accept the rest later is known as currying
  • We immediately call the "wrapper" function, passing it an empty dictionary: (lambda state: ...)({})
    • This lets us assign a variable state to a value {} without using an assignment statement (eg. state = {})
  • We treat keys and values in state as variable names and bound values
    • This is less cumbersome than using immediately-called lambdas
    • This allows us to mutate the values of variables
    • We use state.setdefault(a, b) instead of a = b and state.get(a) instead of a
  • We use a tuple to chain together our side-effects, like before
  • We use [-1] to extract the last value, which acts like a return statement

Of course this is pretty cumbersome, but we can make a nicer API with helper functions:

# Keeps arguments and values close together for immediately-called functions
callWith = lambda x, f: f(x)

# Returns the `get` and `setdefault` methods of a new dictionary
mkEnv = lambda *_: callWith({},
                            lambda d: (d.get,
                                       lambda k, v: (d.pop(k), d.setdefault(k, v))))

# A helper for providing a function with a fresh `get` and `setdefault`
inEnv = lambda f: callWith(mkEnv(), f)

# Delays the execution of a function
delay = lambda f x: lambda *_: f(x)

# Uses `get` and `set`(default) to mutate values
stateful_lambda = delay(inEnv, lambda get, set: (set('foo', 10),
                                                 set('bar', get('foo') * get('foo')),
                                                 set('foo', 2),
                                                 get('foo') + get('bar'))[-1])
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.