在Python中查找列表中列表的最大值和最小值
我有一个列表,里面又包含了很多小列表。
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
或长度(在接下来的图片中用边界上的端点表示)。
2 个回答
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)
即使你已经澄清了,规则还是有点模糊。你需要先搞清楚想要实现什么规则,才能开始编写代码。
如果这个规则比较简单,你应该能写一个函数,返回匹配得越好值就越高。在这种情况下,你可以把这个函数作为 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, object
的 list
,我把这些元素叫做 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]))