在Python中查找列表中列表的最大值和最小值

-1 投票
2 回答
6956 浏览
提问于 2025-04-17 15:34

我有一个列表,里面又包含了很多小列表。

alist = [[distance1,delta-angle1,object1],[distance2,delta-angle2,object2], [distance3,delta-angle3,object3],...]

我想要找到一个列表,使得它的“距离”最大,同时“角度变化”最小。这两个值分别是每个小列表中的前两个元素。

需要注意的是:distance 是一个浮点数,而 delta-angle 是以度数表示的,范围在 -180 到 180 之间。

我的目标是选择一个距离最长且角度最“直”的列表,但不能仅仅选择距离最长的或角度最“直”的(也就是最小化角度变化)。

补充说明:我无法上传图片,所以这里有一个链接。

https://i.stack.imgur.com/apEfd.jpg

我想避免“回到我之前的位置”,在这种特殊情况下。就像第二张图片所示。

图片 2

第三张图片是理想的情况——因为我还没有想到更好的表达方式:最小化当前方向的角度变化(这个角度变化就是已经存储在 alist 中的 delta-angle),同时最大化可用线段的 distance 或长度(在接下来的图片中用边界上的端点表示)。

图片 3 https://i.stack.imgur.com/apEfd.jpg

2 个回答

0
alist = [[0,0,'b'],[-30,50,'a'],
         [45,63,'d'],[100,170,'d'],
         [-2,15,'p']]

def mM(L):
    x,y,_ = zip(*L)
    return (min(x),max(y))

print mM(alist)

结果

(-30, 170)
1

即使你已经澄清了,规则还是有点模糊。你需要先搞清楚想要实现什么规则,才能开始编写代码。

如果这个规则比较简单,你应该能写一个函数,返回匹配得越好值就越高。在这种情况下,你可以把这个函数作为 key 传给 max(或者可以用 sorted,或者 heapq.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 中的每个元素都是一个包含 distance, angle, objectlist,我把这些元素叫做 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]))

撰写回答