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

2025-01-08 08:50:00
admin
原创
109
摘要:问题描述:我有 OOP 背景,正在尝试学习 Python。我正在使用一个max函数,该函数使用 lambda 表达式返回列表中Player具有最大值的类型的实例。totalScore`players`def winner(): w = max(players, key=lambda p: p.tota...

问题描述:

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

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

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

  1. 这个函数是如何max工作的?它所用的参数是什么?我看了文档,但还是不明白。

  2. max 函数中关键字的用途是什么key?我知道它也用于sort函数上下文中

  3. lambda 表达式的含义?如何理解它们?它们如何工作?

这些都是非常新手的概念性问题,但可以帮助我理解语言。如果你能举例说明,那就更好了。谢谢


解决方案 1:

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

def func(p):
   return p.totalScore     

现在max变成:

max(players, key=func)

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

请注意,这lambda相当于您在 a 的 return 语句中输入的内容def。因此,您不能在 a 内部使用语句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'

解决方案 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

解决方案 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将根据提供给它的对象的key totalScoreplayer进行排序,并将返回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')

解决方案 4:

max 函数如何工作?

它查找可迭代对象中的“最大”项。我假设您可以查找它是什么,但如果不能,它就是您可以循环遍历的内容,即列表或字符串。

max 函数中关键字 key 有什么用?我知道它也用于 sort 函数中

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 可能会让人困惑,而且它们的作用并不是很明显。请点击此处。

解决方案 5:

根据文件:

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

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

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

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

可以想象,对于像 这样的复杂对象,player确定其值以进行比较是很棘手的,因此您需要给出key参数来确定函数如何max确定 each 的值。在这种情况下player,您使用 lambda 函数来表示“获取 eachp并将其用作其比较值”。players`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(一个函数)的 iterable key,它将返回键的最大值(按字母顺序排列)

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

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

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

前任。

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

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

解决方案 7:

这有助于我理解这种模式的工作原理。将密钥视为转换函数/比较指标。

max(data, lambda x: transform_function(x))

这是什么意思呢?假设我们有一个数字列表 [1, 2, 3, 4, 5]。我们的任务是找到正弦结果最大的值。

我们不用将 max 函数应用到数字列表,而是用转换函数转换每个值(这里sin

1 -> sin(1)
2 -> sin(2)
3 -> sin(3)
4 -> sin(4)
5 -> sin(5)

现在,我们对转换后的值应用 max 函数。这将得到sin(2),这是输入 2 的结果,因此max(numbers, lambda x: sin(x))将返回 2。

让我们将这个想法应用到更复杂的情况中。考虑以下词典(例如,有三个温度测量值的城市):

cities = {
    "New York": [10, 12, 13],
    "Los Angeles": [14, 15, 16],
    "Washington": [8, 5, -1],
}

我们的目标是找到温度最高的城市(应该是Los Angeles)。我们需要应用什么适当的变换?用文字表达就是:我们想要看到max温度的 = cities[city],因此max(cities[city])应该是我们的变换。所以我们需要执行以下操作。

max(cities, key=lambda city: max(cities[city]))

您甚至可以使用嵌套字典来实现这一点。

cities: dict = {
    "New York": {
        "temperatures": [1, 2, 9],
        "populations": [10000, 20000, 30000],
    },
    "Los Angeles": {
        "temperatures": [4, 5, 4],
        "populations": [40000, 50000, 60000],
    },
    "Washington": {
        "temperatures": [1, 0, -1],
        "populations": [10000, 1000, 0],
    }
}
    
max(cities, key=lambda city: max(cities[city]["populations"]))

解决方案 8:

假设访问此页面的人确实想知道key=其中的内容len(),那么这里有一个简单的答案:

len()计算对象的长度。如果我们len在 中指定为键函数min()max()它将根据其长度返回最小/最大项目。

food = ['bread', 'tea', 'banana', 'kiwi', 'tomato']

print(max(food, key=len))   # banana
print(min(food, key=len))   # tea
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2974  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1836  
  PLM(产品生命周期管理)系统在企业的产品研发、生产与管理过程中扮演着至关重要的角色。然而,在实际运行中,资源冲突是经常会遇到的难题。资源冲突可能导致项目进度延迟、成本增加以及产品质量下降等一系列问题,严重影响企业的效益与竞争力。因此,如何有效应对PLM系统中的资源冲突,成为众多企业关注的焦点。接下来,我们将详细探讨5...
plm项目管理系统   47  
  敏捷项目管理与产品生命周期管理(PLM)的融合,正成为企业在复杂多变的市场环境中提升研发效率、增强竞争力的关键举措。随着技术的飞速发展和市场需求的快速更迭,传统的研发流程面临着诸多挑战,而将敏捷项目管理理念融入PLM,有望在2025年实现研发流程的深度优化,为企业创造更大的价值。理解敏捷项目管理与PLM的核心概念敏捷项...
plm项目   47  
  模块化设计在现代产品开发中扮演着至关重要的角色,它能够提升产品开发效率、降低成本、增强产品的可维护性与可扩展性。而产品生命周期管理(PLM)系统作为整合产品全生命周期信息的关键平台,对模块化设计有着强大的支持能力。随着技术的不断发展,到 2025 年,PLM 系统在支持模块化设计方面将有一系列令人瞩目的技术实践。数字化...
plm软件   48  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用