Welcome, @GeriReshef !
Good question. The basic distinction between creating a function with
def and a
lambda expression, besides syntactic sugar, is that
lambda does so without assigning to a name; in fact, the other common name for a lambda is an anonymous function. If you’re going to create a lambda function and immediately assign to a name, it is much clearer, more idiomatic, easier to read, and more flexible and powerful to simply use
def. Thus, I’d argue that the beginner example above is a rather poor example of using a
lambda, both because it is widely considered a bad practice to use a
lambda that way, but also fails to illustrate the primary reason why/use case where you’d use one, and the distinction between a lambda and a regular function
Essentially, you can think of
lambdas as small throwaway functions you pass to something else immediately upon creation. Typically, you’ll see them used when you need to pass one function as an argument to another. For example, if you have some list
spam of various strings (e.g.
["a1", "b2", "c3"]) and want to sort them as numbers rather than lexically, you could do
sorted(spam, lambda x: int(x)), instead of having to define a whole new function just for this simple task. Or, suppose you have some
timer that calls a function you pass it at a later time. If you wanted to do something simple, a
lambda might be a good choice, e.g.
timer.do_later(lambda: print("Time to wakeup!")). Does that make sense?
If you’re going to reuse a function more than once, use
def—that’s what its for, for the reasons above. The whole intention of a
lambdas (again, aka anonymous functions) are for throwaway, use-once functions that you don’t want to bother giving a name, because you’re not going to use them again.
To each their own, but lines are free, while time, clarity, explicitness and readability are not—it may look clear to you right now, but in the long term it is harder for others (or you, if you come back later) to read and understand your code, harder to annotate it, and harder to spot bugs. Per
import this, the Zen of Python, “Explicit is better than implicit,” “Sparse is better than dense,” “Readability counts,” and most importantly, “There should be one—and preferably only one—obvious way to do it.”
Nope, and there are a number of disadvantages for non-trivial functions—less clear and obvious syntax, much less powerful, can only be one line, more complex to understand, and you don’t get as useful help, tracebacks, etc.
Using a list comprehension is generally an alternative to using a
lambda function with
filter(), unless you’re making a list of simple functions, in which case
lambda is useful to avoid having to define your functions beforehand (given you cannot, of course, use the
def statement within a list comprehension, as the latter must contain only an expression).
Not really; each has their clearly defined use case, and it is strongly discouraged (and sometimes impossible) to use one where the other is more appropriate. As mentioned, lambdas are anonymous functions, and are used when you only need the function one place and don’t want to give it a name, whereas regular
def functions are for other cases.
I don’t mean to be dunking on
lambdas here—they are useful for the specific purposes for which they are intended, and I do use them a fair bit in scientific computing. But like anything, they have their place and are not really a replacement for a regular named function.