【问题标题】:python max function using 'key' and lambda expression使用'key'和lambda表达式的python max函数
【发布时间】:2013-08-18 07:33:12
【问题描述】:

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

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

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

  1. max 函数是如何工作的?它的论据是什么?我查看了文档,但没看懂。
  2. 关键字key在max函数中有什么用?我知道它也用于sort 函数的上下文中
  3. lambda 表达式的含义?如何阅读它们?它们是如何工作的?

这些都是非常无聊的概念性问题,但会帮助我理解语言。如果你能举出例子来解释会有所帮助。 谢谢

【问题讨论】:

  • 哪个 Python 版本?
  • 您咨询过documentation吗?
  • @charmlessCoin python 2.7.5
  • @InbarRose 我检查了 max 函数的文档。没看懂。
  • @InbarRose 这个页面现在实际上是python max lambda 在 Google 上的最高搜索结果,也许实际上可能对新用户更有帮助。

标签: python function lambda


【解决方案1】:

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

def func(p):
   return p.totalScore     

现在max 变为:

max(players, key=func)

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

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


max 有什么作用?

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

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

所以,它只是返回最大的对象。


key 是如何工作的?

默认情况下,在 Python 2 中,key 根据对象的类型(例如,字符串总是大于整数)比较基于 set of rules 的项目。

要在比较之前修改对象,或根据特定属性/索引进行比较,您必须使用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]

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

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

【讨论】:

  • 我认为这是旧的,但我对此有疑问。我看到对于 lambda 函数,变量 x 或 i 或其他任何东西总是代表列表中该索引处的值。这个迭代是由 max 函数还是由 lambda 完成的? lambda 函数是否总是迭代可能的值?例如:lengths = map(lambda word: len(word), words) where words=['It', 'is', 'raining', 'cats', 'and', 'dogs'] 我看到 lambda 正在遍历列表中的每个单词。它总是这样吗?
  • @Mo2 迭代由max 而非lambdakey arg 是可选的)完成,并且在迭代过程中,每一项都传递给key 中指定的函数,返回值为然后用于比较。
  • 只为通过谷歌搜索“最大关键参数”来到这里的人。 max(lis, key=lambda x:int(x)) 可以简化为max(lis, key=int)。 Python 有一个内置函数 int()。同样,您可以使用任何其他内置函数作为key 参数。例如,您可以通过max(lis, key=len)lis=['a', 'aa', 'aaa'] 获取最长的字符串
  • @YOUNG 我们可以使用任何函数作为关键参数,而不仅仅是内置函数,唯一的条件是函数应该接受maxminsorted 等传递给它的项目适当地。另外,我在最后提到了max(lis, key=int)。 :-)
  • @Ashwini Chaudhary .. 假设如果我有一个类似 [1,2,3,4,5] 的列表。这里所有的项目都是不同的。我正在使用给定的函数 max(set(mylist),key=mylist.count) 来查找最常见的项目。因为在这种情况下没有重复的元素。它返回最低的项目。在这种情况下,我们可以做点什么让它返回零或 null。
【解决方案2】:

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

【讨论】:

  • 如果在 lambda 中使用 input(),这个版本会出错。
  • 所以,那个“key”不是dict中的key,它是“在比较之前计算影响值的函数”,所以它是一个作为输入的函数......
【解决方案3】:

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。因此,传递给函数max 的可迭代对象将根据给它的player 对象的key totalScore 进行排序,并返回最大totalScoreplayer

如果没有提供 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')

【讨论】:

    【解决方案4】:

    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 执行此操作,并将两者相加。

    用不那么简单的术语来说,lambdas 来自 lambda calculus,即函数返回函数的思想;一个非常酷的数学概念,用于表达计算。你可以阅读here,然后真正理解here

    多读一点可能会更好,因为 lambdas 可能会造成混淆,而且它们的用处不是很明显。检查here

    【讨论】:

      【解决方案5】:

      根据documentation

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

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

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

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

      正如您所想象的,对于像player 这样的复杂对象,确定其比较值是很棘手的,因此您将获得key 参数来确定max 函数将如何确定每个@987654327 的值@。在这种情况下,您使用 lambda 函数来表示“对于 players 中的每个 p,获取 p.totalscore 并将其用作比较值”。

      【讨论】:

        【解决方案6】:

        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 的函数),它会返回键的最大值(按字母顺序)

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

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

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

        例如

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

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

        【讨论】:

          猜你喜欢
          • 2013-08-20
          • 2016-04-10
          • 2013-03-29
          • 1970-01-01
          • 1970-01-01
          • 2015-05-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多