简体   繁体   中英

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

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.

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 (ie 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.

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

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.

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)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM