【发布时间】:2020-09-12 06:30:23
【问题描述】:
朱莉娅同学(ns) :)
我无法根据元组向量的最小值要求找出选择元组的最有效方法,下面的示例应该有助于理解
A = [(10,1), (34,2), (5,3)]
对于上面的元组向量,我想选择数组内所有元组的第一个元素中第一个元素最小的元组,对于上面的情况应该是
(5,3)
我已经研究了几个小时,但仍然无法找到没有循环 + 虚拟变量的方法?
感谢任何帮助:D
【问题讨论】:
朱莉娅同学(ns) :)
我无法根据元组向量的最小值要求找出选择元组的最有效方法,下面的示例应该有助于理解
A = [(10,1), (34,2), (5,3)]
对于上面的元组向量,我想选择数组内所有元组的第一个元素中第一个元素最小的元组,对于上面的情况应该是
(5,3)
我已经研究了几个小时,但仍然无法找到没有循环 + 虚拟变量的方法?
感谢任何帮助:D
【问题讨论】:
此外,如果您的元组包含支持所有维度(不仅是第一个维度)比较的对象,或者您知道第一个维度是唯一的(因此下一个维度永远不会用于比较),那么您也可以这样做:
julia> argmin(A)
3
julia> minimum(A)
(5, 3)
对于元组 argmin 和 minimum 默认使用字典比较。
这将失败,例如这种情况(您在第一个维度上打成平手,而第二个维度不支持比较):
julia> argmin([(1,im), (1,im)])
ERROR: MethodError: no method matching isless(::Complex{Bool}, ::Complex{Bool})
但这是因为拳头维度没有联系:
julia> argmin([(2,im), (1,im)])
2
另请注意,在与@mcabbott 给出的解决方案有关联的情况下,如果您在最小值有关联,这可能会有所不同:
julia> A = [(1,2), (1,1)]
2-element Array{Tuple{Int64,Int64},1}:
(1, 2)
(1, 1)
julia> argmin(first.(A))
1
julia> argmin(A)
2
因为使用first. 将返回第一个维度上第一次出现的最小值,而不使用first. 将返回所有维度上第一次出现的最小值。
但是,如果您的问题满足我在这里给出的条件(这在实践中很可能),那么我的解决方案会更快,因为它是非分配的。
最后,如果您想要一个非分配且工作方式与@mcabbott 提案相同的解决方案,请使用reduce,如下所示:
julia> A = [(10,1), (34,2), (5,3)]
3-element Array{Tuple{Int64,Int64},1}:
(10, 1)
(34, 2)
(5, 3)
julia> reduce((x,y) -> y[2][1] < x[2][1] ? y : x, enumerate(A))
(3, (5, 3))
julia> A = [(1,im), (1,im)]
2-element Array{Tuple{Int64,Complex{Bool}},1}:
(1, im)
(1, im)
julia> reduce((x,y) -> y[2][1] < x[2][1] ? y : x, enumerate(A))
(1, (1, im))
julia> A = [(1,2), (1,1)]
2-element Array{Tuple{Int64,Int64},1}:
(1, 2)
(1, 1)
julia> reduce((x,y) -> y[2][1] < x[2][1] ? y : x, enumerate(A))
(1, (1, 2))
【讨论】:
不幸的是,findmin 并没有像 sort 那样使用函数来告诉它要看什么。但是你可以通过先分离first.(B)然后调用argmin来找到索引:
julia> B = [(10,1), (77,7), (34,2), (5,3)];
julia> sort(B, by=first)[1]
(5, 3)
julia> B[argmin(first.(B))]
(5, 3)
【讨论】:
reduce 很聪明,但也很拗口。以某种方式内置它会很好,例如by=first 或其他东西。 (我最初误读了这个问题,因为我想按最后一个条目进行排序。)