2

Are there difference between defining a named function in terms of lambda expressions and using def?

For example, are the following two ways defining two equivalent functions?

adder = lambda x, y: x+y

and

def adder(x,y):
    return x+y

Thanks.

  • 4
    Possible duplicate of [what is the difference for python between lambda and regular function?](https://stackoverflow.com/questions/12264834/what-is-the-difference-for-python-between-lambda-and-regular-function) – chickity china chinese chicken Sep 06 '17 at 17:17

4 Answers4

3

Structurally they are equivalent. BUT, from PEP 8:

Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier.

Yes: def f(x): return 2*x

No: f = lambda x: 2*x

The first form means that the name of the resulting function object is specifically 'f' instead of the generic 'lambda'. This is more useful for tracebacks and string representations in general. The use of the assignment statement eliminates the sole benefit a lambda expression can offer over an explicit def statement (i.e. that it can be embedded inside a larger expression

So, this implies you should only use lambdas embedded in larger expressions, for the sake of terser code, rather than assigning an object to them, where the benefit of aesthetic neatness is overwhelmed by the disadvantages named above.

Brad Solomon
  • 38,521
  • 31
  • 149
  • 235
2

Outside of having a name that is convenient for printing, in that example no. A big difference in general though, is you cannot have statements inside a lambda (doesn't apply to your example, but worth knowing).

For example:

def foo():
    x = 2 #can't do in lambda
    return x
Solaxun
  • 2,732
  • 1
  • 22
  • 41
1

Long story short, there is no difference. The only minor difference is the absence of a specific name embedded into the function object. This makes some tools, such as Python's built-in multiprocessing incompatible with lambda-functions, (in case of multiprocessing it is due to pickle's inability to serialise lambdas), though a similar package multiprocess does support them.

Eli Korvigo
  • 10,265
  • 6
  • 47
  • 73
1

There is a difference. Lambdas make it much easier to produce closures which may behave in an unexpected way.

Here's an example:

def create_multipliers_fun():
    def multiplier_factory(i):
        def multiplier(x):
            return i * x
        return multiplier
    # here, an array of functions is returned
    # each multiplies the input value by the value `i` received in the loop
    return [multiplier_factory(i) for i in range(5)]

# prints 0 2 4 6 8
for multiplier in create_multipliers_fun():
    print multiplier(2)

def create_multipliers_lambda():
    # here, all returned functions use the latest available version
    # of the variable `i` (closure with late binding) 
    return [lambda x : i * x for i in range(5)]

# prints 8 8 8 8 8
for multiplier in create_multipliers_lambda():
    print multiplier(2)

Using lambdas it's much less obvious that you're dealing with a late binding closure.

For comparison:

def create_multipliers_closure():
    def multiplier(x):
        return i * x
    return [multiplier for i in range(5)]
moooeeeep
  • 31,622
  • 22
  • 98
  • 187
  • This is a bit misleading. It's not a difference per se, because you can make the same mistake with `def` functions. This "issue" is simply related to the fact, that Python uses symbolic name binding (this is equally true for `def` and `lambda` functions) – Eli Korvigo Sep 06 '17 at 17:49
  • @EliKorvigo Indeed, but it's much easier and much less obvious to achieve this using lambdas. – moooeeeep Sep 06 '17 at 17:50