我有OOP背景,正在学习python。 我正在使用max函数,它使用lambda表达式来返回在列表玩家中拥有最大总分的玩家类型的实例。

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

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

最大函数是如何工作的?它的论据是什么?我看了文件,但不明白。 在max函数中关键字键的使用是什么?我知道它也用在排序函数的上下文中 lambda表达式的含义?如何阅读?它们是如何工作的?

这些都是非常菜鸟的概念问题,但会帮助我理解语言。如果你能举例解释就好了。 谢谢


当前回答

Lambda是一个匿名函数,它相当于:

def func(p):
   return p.totalScore     

现在max变成:

max(players, key=func)

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

注意,lambda等价于你在def的return语句中放入的内容。因此,你不能在lambda中使用语句,只允许使用表达式。


max是做什么的?

Max (a, b, c,…[, key=func]) ->值 使用单个iterable参数,返回其最大的项。用两个或 更多参数,返回最大的参数。

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


密钥是如何工作的?

在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是一个匿名函数,它相当于:

def func(p):
   return p.totalScore     

现在max变成:

max(players, key=func)

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

注意,lambda等价于你在def的return语句中放入的内容。因此,你不能在lambda中使用语句,只允许使用表达式。


max是做什么的?

Max (a, b, c,…[, key=func]) ->值 使用单个iterable参数,返回其最大的项。用两个或 更多参数,返回最大的参数。

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


密钥是如何工作的?

在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'

max的强简化版本:

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

关于λ:

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

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

Max是一个内置函数,第一个参数为可迭代对象(如list或tuple)

关键字参数key有它的默认值None,但它接受函数求值,将其视为包装器,基于函数求值iterable

考虑这个例子字典:

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

Ex:

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

正如你所看到的,如果你只传递可迭代对象而不传递kwarg(key的函数),它将返回key的最大值(按字母顺序)

前女友。 而不是按字母顺序查找键的最大值,您可能需要根据键的长度查找最大键:

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

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

Ex.

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

在本例中,lambda函数返回对应的字典键值,该键值最大

Max函数用于获取可迭代对象的最大值。

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

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关键字,充当伪函数。当你传递playerobject给它时,它会返回player。totalscore。因此,传递给max函数的可迭代对象将根据给予它的玩家对象的关键totalScore进行排序&将返回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')

根据文档:

max(iterable[, key]) max(arg1, arg2, *args[, key]) Return the largest item in an iterable or the largest of two or more arguments. If one positional argument is provided, iterable must be a non-empty iterable (such as a non-empty string, tuple or list). The largest item in the iterable is returned. If two or more positional arguments are provided, the largest of the positional arguments is returned. The optional key argument specifies a one-argument ordering function like that used for list.sort(). The key argument, if supplied, must be in keyword form (for example, max(a,b,c,key=func)).

这就是说,在你的例子中,你提供了一个列表,在这个例子中是玩家。然后max函数将遍历列表中的所有项,并将它们相互比较以获得“最大值”。

可以想象,对于像玩家这样的复杂对象,确定其比较值是很棘手的,所以你会得到一个关键参数,以确定max函数如何决定每个玩家的值。在本例中,你使用lambda函数表示“对于每个p名玩家,获取p.totalscore并将其作为其比较值”。