Python Tricks :Lambdas Are Single-Expression Functions 原创

简介: Python Tricks :Lambdas Are Single-Expression Functions 原创

Python Tricks: Lambdas Are Single-Expression Functions
The lambda keyword in Python provides a shortcut for declaring small anonymous functions. Lambda functions behave just like regular functions declared with the def keyword. They can be used whenever function objects are required.

For example, this is how you’d define a simple lambda function carrying out an addition:

In [1]: add = lambda x , y: x + y

In [2]: add(5, 4)

You could declare the same add function with the def keyword, but it would be slightly more verbose:

In [3]: def add(x, y):
   ...:      return x + y
In [4]: add(5, 3)
Out[4]: 8

Now you might be wondering. “Why the big fuss about lambdas? If they’re just a slightly more concise version of declaring functions with def, what’s the big deal?”

Take a look at the following example and keep the words funciton expression

In [6]: (lambda x, y: x + y)(5, 4)
Out[6]: 9

Okay, what happened here? I just used lambda to define an “add” function inline and then immediately called it with the arguments 5 and 3.

Conceptually, the lambda expression lambda x, y: x+ y is the same as declaring a function with def, but just written inline. The key difference here is that I didn’t have to bind the function object to a name before I used it. I simply stated the expression I wanted to compute as part of a lambda, and then immediately evaluated it by calling the lambda expression like a regular function.

Before you move on, you might want to play with the previous code example a little to really let the meaning of it sink in. I still remember this taking me a while to wrap my head around. So don’t worry about spending a few minutes in an interpreter session on this. It’ll be worth it.

There’s another syntactic difference between lambdas and regular function definitions. Lambda functions are restricted to a single expression. This means a lambda function can’t use statements or annotations–not even a return statement.

How do you return values from lambdas then? Executing a lambda function evaluates its expression and then automatically returns the expression’s result, so there’s always an implicit(隐式) return statement. That’s why some people refer to lambdas as single expression functions.

Lambdas You Can Use
When should you use lambda functions in your code? Technically, any time you’re expected to supply a function object you can use a lambda expression. And because lambdas can be anonymous, you don’t even need to assign them to a name first.

This can provide a handy and “unbureaucratic” shortcut to defining a function in Python. My most frequent use case for lambdas is writing short and concise key funcs

In [8]: tuples = [(1, 'd'), (2, 'b'), (4, 'a'), (3, 'c')]

In [9]: sorted(tuples, key=lambda x:x[1])
Out[9]: [(4, 'a'), (2, 'b'), (3, 'c'), (1, 'd')]

in the above example, we’re sorting a list of tuples by the second value in each tuple. In this case, the lambda function provide a quick way to modify the sort order. Here’s another sorting example you can play with:

In [10]: sorted(range(-5, 6), key=lambda x: x * x)
Out[10]: [0, -1, 1, -2, 2, -3, 3, -4, 4, -5, 5]

Both examples I showed you have more concise implementations in Python using the built-in operator. Itemgetter() and abs() functions. But I hope you can see how using a lambda gives you much more flexibility. Want to sort a sequence by some arbitrary computed key? No problem. Now you know how to do it.

Here’s another interesting thing about lambdas: Just like regular nested functions, lambdas also work as lexical closures.

What’s a lexical closure? It’s just a fancy name for a function that remembers the values from the enclosing lexical (词汇)scope even when the program flow is no longer in that scope. Here’s (fairly academic) example to illustrate the idea:

In [12]: def make_adder(n):
    ...:     return lambda x: x + n
    ...: 

In [13]: plus_3 = make_adder(3)

In [14]: plus_5 = make_adder(5)

In [15]: plus_3(4)
Out[15]: 7

In [16]: plus_5(4)
Out[16]: 9

In the above example, the x + n lambda can still access the value of n even though it was defined in the make_adder function(the enclosing scope).

Sometimes, using a lambda function instead of a nested function declared with the def keyword can express the programmer’s intent more clearly. But to be honest, this isn’t a common occurrence-at least not in the kind of code that I like to write. So let’s talk a little more about that.

But Maybe You Shouldn’t…
On the one hand, I’m hoping that this chapter got you intrested in exploring Python’s lambda functions. On the other hand, I feel like it’s time to put up another caveat(警告): Lambda functions should be used sparingly and with extraordinary care.

I know I’ve written my fair share of code using lambdas that looked “cool” but were actually a liability for me and my coworkers. If you’re tempted to use a lambda, spend a few seconds(or minutes) to think if it is really the cleanest and most maintanable way to achieve the desired result.

For example, doing something like this to save two lines of code is just silly. Sure, technically it works and it’s a nice enough “trick”. But it’s also going to confuse the next gal or guy(女孩或者男孩) that has to ship a bugfix under a tight deadline:

# Harmful:
In [20]: class Car:
    ...:     rev = lambda self: print("Wroom!")
    ...:     crash = lambda self: print("Boom!")
    ...: 

In [21]: my_car = Car()

In [22]: my_car.crash()
Boom!

I have similar feelings about complicated map() or filter() constructs using lambdas. Usually it’s much cleaner to go with a list comprehension or generator expression:

# Harmful
In [23]: list(filter(lambda x:x % 2 == 0, range(16)))
Out[23]: [0, 2, 4, 6, 8, 10, 12, 14]

 # Better
In [24]: [x for x in range(16) if x % 2 == 0]
Out[24]: [0, 2, 4, 6, 8, 10, 12, 14]

If you find yourself doing anything remotely complex with lambda expressions, consider defining a standalone function with a proper name instead.

Saving a few keystrokes won’t matter in the long run, but your colleagues (and your future self) will appreciate clean and readable code more than terse wizardry.

相关文章
|
1月前
|
Go C++ Python
Python Tricks: String Conversion(Every Class Needs a ___repr__)
Python Tricks: String Conversion(Every Class Needs a ___repr__)
|
1月前
|
Go C# Python
Python Tricks:Python‘s Functions Are First-Class
Python Tricks:Python‘s Functions Are First-Class
|
1月前
|
前端开发 Python
Python Tricks-- Abstract Base Classes Keep Inheritance in Check
Python Tricks-- Abstract Base Classes Keep Inheritance in Check
|
1月前
|
C++ Python
Python Tricks--- Object Comparisons:“is” vs “==”
Python Tricks--- Object Comparisons:“is” vs “==”
|
1月前
|
Python
Python Tricks: Nothing to Return Here
Python Tricks: Nothing to Return Here
|
1月前
|
C# Python
Python Tricks : Function Argument Unpacking
Python Tricks : Function Argument Unpacking
|
1月前
|
Python
Python Tricks : How to Write Debuggable Decorators
Python Tricks : How to Write Debuggable Decorators
|
1月前
|
Linux Go Python
Python Tricks :The Power Of Decorators
Python Tricks :The Power Of Decorators
|
1月前
|
安全 JavaScript 前端开发
Python Tricks: A Shocking Truth About String Formatting(二)
Python Tricks: A Shocking Truth About String Formatting(二)
|
1月前
|
API Python
Python Tricks : Fun With args and kwargs
Python Tricks : Fun With args and kwargs