使用'key'和lambda表达式的python max函数


180

我来自OOP背景,尝试学习python。我正在使用max使用lambda表达式返回列表中Player具有最大类型的实例的函数。totalScoreplayers

def winner():
    w = max(players, key=lambda p: p.totalScore)

该函数正确返回Player具有maximum 类型的实例totalScore。我对以下三件事感到困惑:

  1. max功能如何工作?它正在采取什么论点?我查看了文档,但听不懂。
  2. keymax函数中关键字的用途是什么?我知道它也用于sort功能上下文
  3. lambda表达式的含义?如何阅读它们?它们如何运作?

这些都是非常笨拙的概念性问题,但可以帮助我理解语言。如果您可以提供示例进行解释,将有所帮助。谢谢


哪个Python版本?
charmlessCoin13年

2
您查阅过文档吗?
Inbar Rose

@charmlessCoin python 2.7.5
Vijay

2
@InbarRose我检查了文档以获取最大功能。不太了解。
维杰

10
@InbarRose此页面实际上已成为Google上排名第一的结果python max lambda,也许对新用户可能更有帮助。
2015年

Answers:


274

lambda 是一个匿名函数,它等效于:

def func(p):
   return p.totalScore     

现在max变成:

max(players, key=func)

但是由于def语句是复合语句,因此不能在需要表达式的地方使用它们,这就是有时lambda使用的原因。

请注意,这lambda等效于您在的return语句中输入的内容def。因此,您不能在内使用语句lambda,仅允许使用表达式。


怎么max办?

max(a,b,c,... [,key = func])->值

使用单个可迭代参数,返回其最大的项目。具有两个或更多参数,返回最大参数。

因此,它仅返回最大的对象。


key工作如何?

在Python 2中,默认情况下会key根据对象类型(例如,字符串始终大于整数)基于一组规则比较项目。

要在比较之前修改对象,或基于特定的属性/索引进行比较,必须使用key参数。

范例1:

一个简单的示例,假设您有一个字符串形式的数字列表,但是您想按其整数值比较这些项目。

>>> lis = ['1', '100', '111', '2']

这里max使用它们的原始值比较项目(按字母顺序比较字符串,这样您就可以得到'2'输出):

>>> max(lis)
'2'

要通过整数比较项目,请使用key简单的lambda

>>> max(lis, key=lambda x:int(x))  # compare `int` version of each item
'111'

示例2:应用于max元组列表。

>>> lis = [(1,'a'), (3,'c'), (4,'e'), (-1,'z')]

默认情况下,max将按第一个索引比较项目。如果第一个索引相同,则将比较第二个索引。在我的示例中,所有项目都有唯一的第一个索引,因此您将获得以下答案:

>>> max(lis)
(4, 'e')

但是,如果您想通过索引1的值比较每个项目,该怎么办?简单:使用lambda

>>> max(lis, key = lambda x: x[1])
(-1, 'z')

比较包含不同类型对象的可迭代项

混合项目清单:

lis = ['1','100','111','2', 2, 2.57]

在Python 2中,可以比较两种不同类型的项目

>>> max(lis)  # works in Python 2
'2'
>>> max(lis, key=lambda x: int(x))  # compare integer version of each item
'111'

但是在Python 3中,您不能再这样做了

>>> lis = ['1', '100', '111', '2', 2, 2.57]
>>> max(lis)
Traceback (most recent call last):
  File "<ipython-input-2-0ce0a02693e4>", line 1, in <module>
    max(lis)
TypeError: unorderable types: int() > str()

但这可行,因为我们正在比较每个对象的整数版本:

>>> max(lis, key=lambda x: int(x))  # or simply `max(lis, key=int)`
'111'

我认为这已经很老了,但是我对此有疑问。对于lambda函数,我看到变量x或i或其他任何值始终代表列表中该索引处的值。此迭代是由max函数还是由lambda完成的?lambda函数是否总是迭代可能的值?例如:lengths = map(lambda word: len(word), words)在那里words=['It', 'is', 'raining', 'cats', 'and', 'dogs']我看到拉姆达遍历列表中的每一个字。它总是这样做吗?
Mo2

1
@ MO2迭代通过进行maxlambdakeyarg是可选的),和迭代过程中的每个项目被传递到指定的功能key,然后将返回值用于比较。
Ashwini Chaudhary 2014年

2
仅针对通过谷歌搜索“最大关键参数”来到这里的人。max(lis, key=lambda x:int(x))可以简化为max(lis, key=int)。Python具有内置函数int()。同样,您可以使用任何其他内置函数作为key参数。例如,您可以从获得最长的串lis=['a', 'aa', 'aaa']通过max(lis, key=len)
YOUNG

1
@YOUNG我们可以使用任何功能键参数不只是内置功能,唯一的条件是,函数应该接受传递给它的项目maxminsorted等正常。另外,我max(lis, key=int)在最后提到了。:-)
Ashwini Chaudhary 2015年

@Ashwini Chaudhary ..假设我有一个类似[1,2,3,4,5]的列表。这里所有项目都不一样。我正在使用给定的函数max(set(mylist),key = mylist.count)查找最频繁的项目。因为在这种情况下,没有重复的元素。它返回最低的项目。我们可以做点什么让它在这种情况下返回零或null。
维克兰特·拉娜

12

的高度简化版本max

def max(items, key=lambda x: x):
    current = item[0]
    for item in items:
        if key(item) > key(current):
            current = item
    return current

关于lambda:

>>> ident = lambda x: x
>>> ident(3)
3
>>> ident(5)
5

>>> times_two = lambda x: 2*x
>>> times_two(2)
4

10

max函数如何工作?

它寻找可迭代的“最大”项。我假设您可以查找内容,但如果不是,则可以循环查找,即列表或字符串。

max函数中关键字key的用途是什么?我知道它也用于排序功能的上下文中

Key是一个lambda函数,它将告诉max可迭代对象中的哪些对象大于其他对象。假设您正在排序自己创建的某个对象,而不是像整数这样的显而易见的对象。

lambda表达式的含义?如何阅读它们?它们如何运作?

这是一个更大的问题。简单来说,lambda是一个您可以传递的功能,并且其他代码也可以使用它。以这个为例:

def sum(a, b, f):
    return (f(a) + f(b))

这需要两个对象,ab和一个函数f。它调用f()每个对象,然后将它们添加在一起。所以看这个电话:

>>> sum(2, 2, lambda a:  a * 2)
8

sum()需要2,并在其上调用lambda表达式。因此f(a)变为2 * 2,变为4。然后为进行此操作b,并将两者加在一起。

用不那么简单的术语来说,lambda来自lambda演算,这是一个返回函数的函数。用于表达计算的非常酷的数学概念。你可以阅读有关在这里,然后居然明白在这里

最好多读一遍,因为lambda可能会造成混淆,而且还不清楚它们的用处。在这里检查。


7

max函数用于获取最大值iterable

迭代器可以是列表,元组,字典对象等。甚至可以像您提供的示例中那样是自定义对象。

max(iterable[, key=func]) -> value
max(a, b, c, ...[, key=func]) -> value

With a single iterable argument, return its largest item.
With two or more arguments, return the largest argument.

因此,key=func基本上,我们可以将一个可选参数传递key给该函数,在该函数的基础上,对给定的迭代器/参数进行排序并返回最大值。

lambda是一个充当伪函数的python关键字。因此,当您将player对象传递给它时,它将返回player.totalScore。因此,传递给函数的iterable max将根据提供给它的对象的key totalScore进行排序,player并返回player具有maximum 的who totalScore

如果未key提供任何参数,则根据默认的Python顺序返回最大值。

例子 -

max(1, 3, 5, 7)
>>>7
max([1, 3, 5, 7])
>>>7

people = [('Barack', 'Obama'), ('Oprah', 'Winfrey'), ('Mahatma', 'Gandhi')]
max(people, key=lambda x: x[1])
>>>('Oprah', 'Winfrey')

6

根据文档

max(iterable [,key])
max(arg1,arg2,* args [,key])
返回可迭代的最大项目或两个或多个参数中的最大项目。

如果提供了一个位置参数,则iterable必须是非空的Iterable(例如,非空的字符串,元组或列表)。返回iterable中最大的项目。如果提供了两个或多个位置自变量,则返回最大的位置自变量。

可选的key参数指定一个单参数排序函数,例如用于list.sort()的函数。如果提供了key参数,则必须采用关键字形式(例如max(a,b,c,key = func))。

这就是说,在这种情况下,您要提供一个列表players。然后,该max函数将遍历列表中的所有项目,并将它们相互比较以获得“最大值”。

可以想象,使用复杂的对象(例如player确定其比较值)比较棘手,因此将为您提供key参数,以确定max函数如何确定每个对象的值player。在这种情况下,您使用的是lambda函数,说“对于每个pin playersget p.totalscore并将其用作比较的值”。


3

max内置函数,该函数接受第一个参数iterable(例如列表或元组)

关键字参数key具有默认值,None但它接受要评估的函数,将其视为基于函数评估可迭代的包装器

考虑以下示例字典:

d = {'aim':99, 'aid': 45, 'axe': 59, 'big': 9, 'short': 995, 'sin':12, 'sword':1, 'friend':1000, 'artwork':23}

例如:

>>> max(d.keys())
'sword'

如您所见,如果只传递不带kwarg的可迭代对象(将函数传递给key),它将返回key的最大值(按字母顺序)

例如 可能不是需要按字母顺序查找键的最大值,而是可能需要根据键的长度查找最大键:

>>>max(d.keys(), key=lambda x: len(x))
'artwork'

在此示例中,lambda函数返回的键长度将被迭代,因此在评估值而不是按字母顺序考虑时,它将跟踪键的最大长度并返回具有最大长度的键

例如

>>> max(d.keys(), key=lambda x: d[x])
'friend'

在此示例中,lambda函数返回具有最大值的相应字典键的值

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.