max(dict, dict.get) 当字典项是 NamedTuple 对象时

max(dict, dict.get) when dict items are NamedTuple objects

我的目标是找到字典中相似度参数最高的元素的id。

我不确定我是否理解为什么这两种方法工作相同,如果有人能解释一下,我将不胜感激。

这是我的 python 3.6 代码:


class ParentCandidate(NamedTuple):
    similarity: float
    title: str


c1 = ParentCandidate(0.875, 'longest title 1')
c2 = ParentCandidate(1, 'title 2')
c3 = ParentCandidate(0.9, 'title 3')
c4 = ParentCandidate(1.1, 'title 4')
c5 = ParentCandidate(0.5, 'title 5')

candidates = {1: c1, 2: c2, 3: c3, 4: c4, 5: c5}

closest_method1 = max(candidates, key=candidates.get)
closest_method2 = max(candidates, key=lambda sim: candidates[sim].similarity)
print(closest_method1, closest_method2)
assert closest_method1 == closest_method2

第二种方法完全按计划工作,而且我们直接引用它时如何确定最大相似度值似乎很清楚。 虽然我根本不明白 max() 函数在接收 NamedTuple 对象进行比较时如何能够完成它的工作。

简化它。将 NamedTuples 和 max 直接从等式中取出:

>>> (0.9, 'title 3') > (0.5, 'title 5')
True

元组可以直接比较。最初,检查第一个元素。由于 0.9 大于上面的 0.5 ,因此第一个元组被认为更大。如果第一个元素相同,它会移动到第二个元素并检查它们。它重复该过程,直到找到一组元素,其中一个更大,或者它们被认为是相等的。


max(candidates, key=candidates.get)

这基本上是对该想法的扩展,并检查 NamedTuple 中的哪一个(从元组继承行为)是最好的。这实际上意味着它正在检查元组的第一个元素,但请注意,如果您有两个具有相同 similarity 的元素,它将移至 title 元素并对字符串进行字典排序!这可能不是您想要的,所以我将跳过使用该变体。

它们并不完全相同。第一种方法比较整个元组,第二种方法只比较 similarity 元素。第一种方法相当于

closest_method = max(candidates, key=lambda sim: candidates[sim])

candidates.get(x) 等同于 candidates[x]x 是字典的键时。并且由于 max() 遍历密钥,因此在此上下文中不会发生密钥不存在的情况(索引引发异常, .get() returns None by默认)。

如果所有 similarity 元素都是唯一的,那么这两种方法之间不会有区别。但是如果有重复的 similarity 值,.get() 方法将比较标题以对它们进行排序。