sorted(key = lambda:…)后面的语法

问题:sorted(key = lambda:…)后面的语法

我不太明白该sorted()参数背后的语法:

key=lambda variable: variable[0]

是不是lambda随心所欲?为什么variable在一个什么样的表述中两次dict

I don’t quite understand the syntax behind the sorted() argument:

key=lambda variable: variable[0]

Isn’t lambda arbitrary? Why is variable stated twice in what looks like a dict?


回答 0

key是一个函数,在比较集合的项目之前将调用该函数。传递给的参数key必须是可调用的。

使用lambda创建一个匿名函数(可调用)。在sorted可调用的情况下仅采用一个参数。Python lambda很简单。它只能做并真正返回一件事。

语法lambda是单词,lambda后跟参数名称列表,然后是单个代码块。参数列表和代码块用冒号表示。这类似于在python其他构建体,以及诸如whileforif等。它们都是通常具有代码块的语句。Lambda只是带有代码块的语句的另一个实例。

我们可以将lambda与def的使用进行比较,以创建一个函数。

adder_lambda = lambda parameter1,parameter2: parameter1+parameter2
def adder_regular(parameter1, parameter2): return parameter1+parameter2

lambda只是为我们提供了一种无需分配名称的方法。这非常适合用作函数的参数。

variable 在此使用两次,因为在冒号的左手边它是参数的名称,而在右手边它在代码块中用于计算某些内容。

key is a function that will be called to transform the collection’s items before they are compared. The parameter passed to key must be something that is callable.

The use of lambda creates an anonymous function (which is callable). In the case of sorted the callable only takes one parameters. Python’s lambda is pretty simple. It can only do and return one thing really.

The syntax of lambda is the word lambda followed by the list of parameter names then a single block of code. The parameter list and code block are delineated by colon. This is similar to other constructs in python as well such as while, for, if and so on. They are all statements that typically have a code block. Lambda is just another instance of a statement with a code block.

We can compare the use of lambda with that of def to create a function.

adder_lambda = lambda parameter1,parameter2: parameter1+parameter2
def adder_regular(parameter1, parameter2): return parameter1+parameter2

lambda just gives us a way of doing this without assigning a name. Which makes it great for using as a parameter to a function.

variable is used twice here because on the left hand of the colon it is the name of a parameter and on the right hand side it is being used in the code block to compute something.


回答 1

我认为这里的所有答案都很好地涵盖了lambda函数在sorted()上下文中的作用的核心,但是我仍然感觉缺乏对直观理解的描述,所以这里是我的两分钱。

为了完整起见,我先说一下显而易见的事情:sorted()返回已排序元素的列表,以及是否要以特定方式排序或是否要对元素的复杂列表进行排序(例如,嵌套列表或元组列表),我们可以调用key参数。

对我来说,关键参数的直观理解,为什么它必须是可调用的以及使用lambda作为(匿名)可调用函数来完成此操作的过程分为两个部分。

  1. 最终,使用lamba意味着您不必编写(定义)整个函数,就像一个例子所提供的那样。Lambda函数可以被创建,使用和立即销毁-因此它们不会使您的代码与只会被使用一次的更多代码捆绑在一起。据我了解,这是lambda函数的核心实用程序,它在此类角色中的应用广泛。它的语法纯属约定,从本质上讲,这通常是程序语法的本质。学习语法并完成它。

Lambda语法如下:

lambda input_variable(s)好吃的一班轮

例如

In [1]: f00 = lambda x: x/2

In [2]: f00(10)
Out[2]: 5.0

In [3]: (lambda x: x/2)(10)
Out[3]: 5.0

In [4]: (lambda x, y: x / y)(10, 2)
Out[4]: 5.0

In [5]: (lambda: 'amazing lambda')() # func with no args!
Out[5]: 'amazing lambda'
  1. key参数背后的想法是,它应该接受一组指令,这些指令本质上将把“ sorted()”功能指向那些应该用于排序的列表元素。当它说时key=,它的真正含义是:当我一次遍历列表中的一个元素时(即对于列表中的e),我将把当前元素传递给我在key参数中提供的函数,并使用该元素。创建一个转换后的列表,该列表将通知我最终排序列表的顺序。

看看这个:

mylist = [3,6,3,2,4,8,23]
sorted(mylist, key=WhatToSortBy)

基本示例:

sorted(mylist)

[2、3、3、4、6、8、23]#所有数字按从小到大的顺序排列。

范例1:

mylist = [3,6,3,2,4,8,23]
sorted(mylist, key=lambda x: x%2==0)

[3,3,23,6,2,4,8]#此排序结果对您来说是否直观?

请注意,我的lambda函数告诉sorted在排序之前检查(e)是偶数还是奇数。

可是等等!您可能(或者也许应该)想知道两件事-首先,为什么我的赔率比我的赔率还要高(因为我的关键值似乎是在告诉我的排序函数通过使用中的mod运算符来优先考虑偶数x%2==0)。第二,为什么我的偶数不正常?2先于6吧?通过分析此结果,我们将更深入地了解sorted()’key’参数如何工作,尤其是与匿名lambda函数结合使用时。

首先,您会注意到虽然赔率先于偶数,但偶数本身并未排序。为什么是这样??让我们阅读文档

关键函数从Python 2.4开始,list.sort()和sorted()都添加了一个关键参数,以指定要在进行比较之前在每个列表元素上调用的函数。

我们必须在这里在各行之间进行一些阅读,但这告诉我们,sort函数仅被调用一次,并且如果我们指定key参数,那么我们将按key函数指向我们的值进行排序。

那么使用模数返回的示例又是什么呢?布尔值:True == 1False == 0。那么排序如何处理这个键?它基本上将原始列表转换为1和0的序列。

[3,6,3,2,4,8,23]变为[0,1,0,1,1,1,0]

现在我们到了某个地方。对转换后的列表进行排序会得到什么?

[0,0,0,1,1,1,1]

好的,现在我们知道了为什么赔率要高于平均赔率了。但是,下一个问题是:为什么最终列表中的6仍然排在2之前?嗯,这很容易-因为排序只发生一次!即那些1仍然代表原始列表值,它们处于彼此相对的原始位置。由于排序仅发生一次,并且我们不调用任何排序函数来将原始偶数值从低到高排序,因此这些值相对于彼此保持原始顺序。

那么最后的问题是:当我打印出最终的排序列表时,我如何在概念上思考布尔值的顺序如何转换回原始值?

Sorted()是一种内置方法(事实)使用称为Timsort的混合排序算法结合了合并排序和插入排序的各个方面。在我看来,当您调用它时,有一种机制可以将这些值保存在内存中,并将它们与由(…!)lambda函数确定的布尔标识(掩码)捆绑在一起。顺序由通过lambda函数计算出的布尔身份确定,但请记住,这些子列表(一个和一个零)本身并不按其原始值排序。因此,最终列表虽然由奇数和偶数组织,但不会按子列表排序(在这种情况下,偶数是乱序的)。赔率排序的事实是因为它们在原始列表中已经是巧合的。从所有这些中得出的结论是,当lambda进行该转换时,将保留子列表的原始顺序。

那么,这一切与原始问题有何关系,更重要的是,我们对如何使用关键参数和lambda实现sorted()的直觉?

该lambda函数可以被视为指向我们需要排序的值的指针,它是将值映射到由lambda函数转换后的布尔值的指针,还是其在嵌套列表tuple中的特定元素, dict等,同样由lambda函数确定。

让我们尝试预测当我运行以下代码时会发生什么。

mylist = [(3, 5, 8), (6, 2, 8), ( 2, 9, 4), (6, 8, 5)]
sorted(mylist, key=lambda x: x[1])

我的sorted电话显然说:“请对该列表进行排序”。关键参数通过对mylist中的每个元素(x)说,返回该元素的索引1,然后按lambda函数。由于我们有一个元组列表,因此我们可以从该元组返回一个索引元素。这样我们得到:

[(6,2,8),(3,5,8),(6,8,5),(2,9,4)]

运行该代码,您会发现这就是命令。尝试索引整数列表,您会发现代码中断。

这是一个冗长的解释,但是我希望这有助于“整理”您对使用lambda函数作为sorted()及以后的关键参数的直觉。

I think all of the answers here cover the core of what the lambda function does in the context of sorted() quite nicely, however I still feel like a description that leads to an intuitive understanding is lacking, so here is my two cents.

For the sake of completeness, I’ll state the obvious up front: sorted() returns a list of sorted elements and if we want to sort in a particular way or if we want to sort a complex list of elements (e.g. nested lists or a list of tuples) we can invoke the key argument.

For me, the intuitive understanding of the key argument, why it has to be callable, and the use of lambda as the (anonymous) callable function to accomplish this comes in two parts.

  1. Using lamba ultimately means you don’t have to write (define) an entire function, like the one sblom provided an example of. Lambda functions are created, used, and immediately destroyed – so they don’t funk up your code with more code that will only ever be used once. This, as I understand it, is the core utility of the lambda function and its applications for such roles are broad. Its syntax is purely by convention, which is in essence the nature of programmatic syntax in general. Learn the syntax and be done with it.

Lambda syntax is as follows:

lambda input_variable(s): tasty one liner

e.g.

In [1]: f00 = lambda x: x/2

In [2]: f00(10)
Out[2]: 5.0

In [3]: (lambda x: x/2)(10)
Out[3]: 5.0

In [4]: (lambda x, y: x / y)(10, 2)
Out[4]: 5.0

In [5]: (lambda: 'amazing lambda')() # func with no args!
Out[5]: 'amazing lambda'
  1. The idea behind the key argument is that it should take in a set of instructions that will essentially point the ‘sorted()’ function at those list elements which should used to sort by. When it says key=, what it really means is: As I iterate through the list one element at a time (i.e. for e in list), I’m going to pass the current element to the function I provide in the key argument and use that to create a transformed list which will inform me on the order of final sorted list.

Check it out:

mylist = [3,6,3,2,4,8,23]
sorted(mylist, key=WhatToSortBy)

Base example:

sorted(mylist)

[2, 3, 3, 4, 6, 8, 23] # all numbers are in order from small to large.

Example 1:

mylist = [3,6,3,2,4,8,23]
sorted(mylist, key=lambda x: x%2==0)

[3, 3, 23, 6, 2, 4, 8] # Does this sorted result make intuitive sense to you?

Notice that my lambda function told sorted to check if (e) was even or odd before sorting.

BUT WAIT! You may (or perhaps should) be wondering two things – first, why are my odds coming before my evens (since my key value seems to be telling my sorted function to prioritize evens by using the mod operator in x%2==0). Second, why are my evens out of order? 2 comes before 6 right? By analyzing this result, we’ll learn something deeper about how the sorted() ‘key’ argument works, especially in conjunction with the anonymous lambda function.

Firstly, you’ll notice that while the odds come before the evens, the evens themselves are not sorted. Why is this?? Lets read the docs:

Key Functions Starting with Python 2.4, both list.sort() and sorted() added a key parameter to specify a function to be called on each list element prior to making comparisons.

We have to do a little bit of reading between the lines here, but what this tells us is that the sort function is only called once, and if we specify the key argument, then we sort by the value that key function points us to.

So what does the example using a modulo return? A boolean value: True == 1, False == 0. So how does sorted deal with this key? It basically transforms the original list to a sequence of 1s and 0s.

[3,6,3,2,4,8,23] becomes [0,1,0,1,1,1,0]

Now we’re getting somewhere. What do you get when you sort the transformed list?

[0,0,0,1,1,1,1]

Okay, so now we know why the odds come before the evens. But the next question is: Why does the 6 still come before the 2 in my final list? Well that’s easy – its because sorting only happens once! i.e. Those 1s still represent the original list values, which are in their original positions relative to each other. Since sorting only happens once, and we don’t call any kind of sort function to order the original even values from low to high, those values remain in their original order relative to one another.

The final question is then this: How do I think conceptually about how the order of my boolean values get transformed back in to the original values when I print out the final sorted list?

Sorted() is a built-in method that (fun fact) uses a hybrid sorting algorithm called Timsort that combines aspects of merge sort and insertion sort. It seems clear to me that when you call it, there is a mechanic that holds these values in memory and bundles them with their boolean identity (mask) determined by (…!) the lambda function. The order is determined by their boolean identity calculated from the lambda function, but keep in mind that these sublists (of one’s and zeros) are not themselves sorted by their original values. Hence, the final list, while organized by Odds and Evens, is not sorted by sublist (the evens in this case are out of order). The fact that the odds are ordered is because they were already in order by coincidence in the original list. The takeaway from all this is that when lambda does that transformation, the original order of the sublists are retained.

So how does this all relate back to the original question, and more importantly, our intuition on how we should implement sorted() with its key argument and lambda?

That lambda function can be thought of as a pointer that points to the values we need to sort by, whether its a pointer mapping a value to its boolean transformed by the lambda function, or if its a particular element in a nested list, tuple, dict, etc., again determined by the lambda function.

Lets try and predict what happens when I run the following code.

mylist = [(3, 5, 8), (6, 2, 8), ( 2, 9, 4), (6, 8, 5)]
sorted(mylist, key=lambda x: x[1])

My sorted call obviously says, “Please sort this list”. The key argument makes that a little more specific by saying, for each element (x) in mylist, return index 1 of that element, then sort all of the elements of the original list ‘mylist’ by the sorted order of the list calculated by the lambda function. Since we have a list of tuples, we can return an indexed element from that tuple. So we get:

[(6, 2, 8), (3, 5, 8), (6, 8, 5), (2, 9, 4)]

Run that code, and you’ll find that this is the order. Try indexing a list of integers and you’ll find that the code breaks.

This was a long winded explanation, but I hope this helps to ‘sort’ your intuition on the use of lambda functions as the key argument in sorted() and beyond.


回答 2

lambda是一个Python关键字,用于生成匿名函数

>>> (lambda x: x+2)(3)
5

lambda is a Python keyword that is used to generate anonymous functions.

>>> (lambda x: x+2)(3)
5

回答 3

variable左侧:是参数名称。采用variable右侧正在使用的参数。

意思几乎完全相同:

def some_method(variable):
  return variable[0]

The variable left of the : is a parameter name. The use of variable on the right is making use of the parameter.

Means almost exactly the same as:

def some_method(variable):
  return variable[0]

回答 4

使用key = lambda的sorted()函数的另一个示例。让我们考虑一下您有一个元组列表。在每个元组中,您都有汽车的品牌,型号和重量,并且您想要按品牌,型号或重量对这个元组列表进行排序。您可以使用lambda来完成。

cars = [('citroen', 'xsara', 1100), ('lincoln', 'navigator', 2000), ('bmw', 'x5', 1700)]

print(sorted(cars, key=lambda car: car[0]))
print(sorted(cars, key=lambda car: car[1]))
print(sorted(cars, key=lambda car: car[2]))

结果:

[('bmw', 'x5', '1700'), ('citroen', 'xsara', 1100), ('lincoln', 'navigator', 2000)]
[('lincoln', 'navigator', 2000), ('bmw', 'x5', '1700'), ('citroen', 'xsara', 1100)]
[('citroen', 'xsara', 1100), ('bmw', 'x5', 1700), ('lincoln', 'navigator', 2000)]

One more example of usage sorted() function with key=lambda. Let’s consider you have a list of tuples. In each tuple you have a brand, model and weight of the car and you want to sort this list of tuples by brand, model or weight. You can do it with lambda.

cars = [('citroen', 'xsara', 1100), ('lincoln', 'navigator', 2000), ('bmw', 'x5', 1700)]

print(sorted(cars, key=lambda car: car[0]))
print(sorted(cars, key=lambda car: car[1]))
print(sorted(cars, key=lambda car: car[2]))

Results:

[('bmw', 'x5', '1700'), ('citroen', 'xsara', 1100), ('lincoln', 'navigator', 2000)]
[('lincoln', 'navigator', 2000), ('bmw', 'x5', '1700'), ('citroen', 'xsara', 1100)]
[('citroen', 'xsara', 1100), ('bmw', 'x5', 1700), ('lincoln', 'navigator', 2000)]

回答 5

lambda是匿名函数,不是任意函数。接受的参数将是您正在使用的变量以及对其进行排序的列。

lambda is an anonymous function, not an arbitrary function. The parameter being accepted would be the variable you’re working with, and the column in which you’re sorting it on.


回答 6

由于在的上下文中询问了lambda的用法,因此也请sorted()看看https://wiki.python.org/moin/HowTo/Sorting/#Key_Functions

Since the usage of lambda was asked in the context of sorted(), take a look at this as well https://wiki.python.org/moin/HowTo/Sorting/#Key_Functions


回答 7

换个说法,排序函数中的键(可选。要执行以决定顺序的函数。默认为None)需要一个函数,而您使用的是lambda。

要定义lambda,请指定要排序的对象属性,而python的内置排序函数将自动处理它。

如果要按多个属性排序,则分配key = lambda x:(property1,property2)。

要指定排序方式,请将sorted函数的第三个参数(可选。布尔值。False将按升序排序,True将按降序排序。默认值为False)传递reverse = true。

Just to rephrase, the key (Optional. A Function to execute to decide the order. Default is None) in sorted functions expects a function and you use lambda.

To define lambda, you specify the object property you want to sort and python’s built-in sorted function will automatically take care of it.

If you want to sort by multiple properties then assign key = lambda x: (property1, property2).

To specify order-by, pass reverse= true as the third argument(Optional. A Boolean. False will sort ascending, True will sort descending. Default is False) of sorted function.


回答 8

简单且不耗时的答案,并提供与所提问题相关的示例,请 按照以下示例操作:

 user = [{"name": "Dough", "age": 55}, 
            {"name": "Ben", "age": 44}, 
            {"name": "Citrus", "age": 33},
            {"name": "Abdullah", "age":22},
            ]
    print(sorted(user, key=lambda el: el["name"]))
    print(sorted(user, key= lambda y: y["age"]))

查看列表中的名称,它们以D,B,C和A开头。如果您注意到年龄,则分别是55、44、33和22。第一个打印代码

print(sorted(user, key=lambda el: el["name"]))

结果为:

[{'name': 'Abdullah', 'age': 22}, 
{'name': 'Ben', 'age': 44}, 
{'name': 'Citrus', 'age': 33}, 
{'name': 'Dough', 'age': 55}]

对名称进行排序,因为通过key = lambda el:el [“ name”]我们对名称进行排序,并且名称按字母顺序返回。

第二次印刷代码

print(sorted(user, key= lambda y: y["age"]))

结果:

[{'name': 'Abdullah', 'age': 22},
 {'name': 'Citrus', 'age': 33},
 {'name': 'Ben', 'age': 44}, 
 {'name': 'Dough', 'age': 55}]

按年龄排序,因此列表按年龄升序返回。

尝试使用此代码可以更好地理解。

Simple and not time consuming answer with an example relevant to the question asked Follow this example:

 user = [{"name": "Dough", "age": 55}, 
            {"name": "Ben", "age": 44}, 
            {"name": "Citrus", "age": 33},
            {"name": "Abdullah", "age":22},
            ]
    print(sorted(user, key=lambda el: el["name"]))
    print(sorted(user, key= lambda y: y["age"]))

Look at the names in the list, they starts with D, B, C and A. And if you notice the ages, they are 55, 44, 33 and 22. The first print code

print(sorted(user, key=lambda el: el["name"]))

Results to:

[{'name': 'Abdullah', 'age': 22}, 
{'name': 'Ben', 'age': 44}, 
{'name': 'Citrus', 'age': 33}, 
{'name': 'Dough', 'age': 55}]

sorts the name, because by key=lambda el: el[“name”] we are sorting the names and the names return in alphabetical order.

The second print code

print(sorted(user, key= lambda y: y["age"]))

Result:

[{'name': 'Abdullah', 'age': 22},
 {'name': 'Citrus', 'age': 33},
 {'name': 'Ben', 'age': 44}, 
 {'name': 'Dough', 'age': 55}]

sorts by age, and hence the list returns by ascending order of age.

Try this code for better understanding.