即使经过澄清,您的规则仍然模棱两可。在编写该规则之前,您需要弄清楚要实施什么规则。
如果规则足够简单,您应该能够编写一个返回值越高匹配越好的函数。在这种情况下,您可以将该函数作为key
to传递max
(或者您可以sorted
、 orheapq.nlargest
等,具体取决于您的实际用例)。
例如,如果规则只是“具有最大 X 分量的对象是最好的”,正如 Blckknght 所说,那就是distance*cos(angle)
. 当然,除了你可能想要最大的正或负 X 分量,所以它实际上是abs(that)
. 所以:
def best(alist):
return max(alist, key=lambda dao: abs(dao[0] * math.cos(dao[1]))
(因为 的每个元素list
都是list
of ,所以distance, angle, object
我称每个元素为 ,距离等也是)dao
dao[0]
如果您不知道如何将规则变成单键功能怎么办?
好吧,如果你可以编写一个比较函数,比较两个dao
三元组并返回更大的一个,你可以用functools.cmp_to_key
它把它变成一个key
函数。但实际上,您可以编写cmp
函数但不能编写key
函数的情况并不常见。
如果你需要更复杂的东西,你总是可以预先过滤列表,或者装饰-排序-取消装饰等。
例如,在评论中,您说:
最大的效用来自于 -90:0:90 范围内的长线,而无论距离有多长,其他一切都几乎没有效用。
这是模棱两可的,但我们可以解释它的一种方式是:
- 如果有任何对象的角度在 [-90, 90] 范围内,请从这些对象中选择最长的。
- 否则,选择角度最小的对象。
我可以把它写成一个关键函数,但是让我们假装我不知道怎么做,并且想让一切都变得明确。为它编写一个键函数是微不足道的longest
——就像dao[0]
键一样。编写一个关键函数smallest angle
也很简单——那就是abs(dao[1])
. 所以:
def best(alist):
acutes = [[d, a, o] for [d, a, o] in alist if abs(a) <= 90]
if acutes:
return max(acutes, key=lambda dao: dao[0])
else:
return min(alist, key=lambda dao: abs(dao[1]))