2013-08-18 26 views
97

我来自OOP背景并试图学习python。 我正在使用max函数,它使用lambda表达式返回列表players中具有最大totalScorePlayer类型的实例。使用'key'和lambda表达式的python max函数

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

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

  1. 如何进行max功能工作?它正在采取什么论据?我看了看文档,但没有明白。
  2. 最大功能中关键字key的用法是什么?我知道它也用于sort函数的背景下
  3. lambda表达式的含义?如何阅读它们?他们如何工作?

这些都是很好的概念性问题,但会帮助我理解语言。如果你能举例说明,这将会有所帮助。 由于

+0

哪一种Python版本? – charmlessCoin

+0

您是否咨询过[documentation](http://docs.python.org/2/library/functions.html#max)? –

+0

@charmlessCoin python 2.7.5 – Vijay

回答

150

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

def func(p): 
    return p.totalScore  

现在max变为:

max(players, key=func) 

但作为def语句是它们不能被用来复合语句,其中的表达是这就是为什么有时使用lambda的原因。

请注意,lambda相当于您在def的返回语句中放入的内容。因此,您不能在lambda内使用语句,只允许使用表达式。


max做什么?

最大值(A,B,C,... [,键= FUNC]) - >值

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

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


How `key` works? 

默认情况下在Python 2键比较基于基于所述对象的类型(例如,字符串总是比的整数)一个set of rules项目。

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

例1:

一个简单的例子,假设你以字符串形式号码清单,而是要通过他们的整数值来比较这些项目。

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

这里max使用其原始值进行比较的项目(字符串字典顺序比较,所以你会得到'2'作为输出):

>>> max(lis) 
'2' 

要通过与他们的整数值使用键比较的品种简单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 will会比较第一个索引的项目,如果第一个索引相同,那么它会比较第二个索引。正如我在示例中,所有的项目具有独特的第一个索引的话,你会得到这样的答案:

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

但是,如果你想每个项目由值索引1比什么?操作简单,使用lambda

名单混合项目:

​​

In Python 2 it is possible to compare items of two different types

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

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

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

But in Python 3 you can't do that any more

>>> 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' 
+0

我认为这是旧的,但我对此有一个问题。我看到了lambda函数,变量x或i或其他任何东西总是表示列表中该索引处的值。这个迭代是由max函数还是由lambda完成的? lambda函数总是迭代可能的值吗?例如:'长度=地图(lambda单词:len(单词),单词)'其中'单词= ['它','是','下雨','猫','和','狗']'我看到lambda遍历列表中的每个单词。它总是这样做吗? – Mo2

+1

@ Mo2迭代通过'max'而不是'lambda'完成('key' arg是可选的),并且在迭代期间,每个项目都被传递给'key'中指定的函数,然后返回的值用于比较。 –

+1

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

8

非常简化的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 
5

按照documentation

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

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

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

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

你可以想像,随着像player一个复杂的对象确定为比较其价值是棘手的,所以您将得到key参数来确定max功能将如何决定每个player的价值。在这种情况下,您正在使用lambda函数来说“对于players中的每个p获得p.totalscore并将其用作比较值”。

8

如何max函数的工作?

它寻找iterable中的“最大”项。我假设你 可以查找那是什么,但如果不是,你可以循环, 即列表或字符串。

在max函数中关键字键的用法是什么?我知道这也是在排序功能的情况下使用

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表达式来自演算,这是一个返回函数的函数的想法;表达计算的一个非常酷的数学概念。您可以阅读关于该here,然后实际上了解它​​。

它可能更好地了解这多一点,因为lambda表达式可能会造成混淆,并且它不是立即明显他们是多么有用。检查here

3

max函数用来获得最大的出iterable的。

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

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。因此,传递给函数max的迭代将根据keytotalScoreplayer给出的对象&将返回player谁拥有最大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')