julia - 如何找到Dict的最小/最大值的关键字?

tss*_*sch 8 dictionary julia

我想找到与朱莉娅字典的最小值或最大值相对应的键.在Python中我会想到以下内容:

my_dict = {1:20, 2:10}
min(my_dict, my_dict.get)
Run Code Online (Sandbox Code Playgroud)

哪个会返回密钥2.

我怎么能在朱莉娅做同样的事情?

my_dict = Dict(1=>20, 2=>10)
minimum(my_dict)
Run Code Online (Sandbox Code Playgroud)

后者返回1 => 20而不是2 => 10或2.

use*_*730 8

您可以使用reduce这样的,它将返回第一个最小值的键d:

reduce((x, y) -> d[x] ? d[y] ? x : y, keys(d))
Run Code Online (Sandbox Code Playgroud)

但这仅适用于非空Dicts.(但是"没有价值的最小值的关键"的概念并不真正有意义,所以通常情况下应该单独处理.)


关于效率的编辑.

考虑这些定义(没有一个处理空集合)......

m1(d) = reduce((x, y) -> d[x] ? d[y] ? x : y, keys(d))

m2(d) = collect(keys(d))[indmin(collect(values(d)))]

function m3(d)
  minindex(x, y) = d[x] ? d[y] ? x : y
  reduce(minindex, keys(d))
end

function m4(d)
  minkey, minvalue = next(d, start(d))[1]
  for (key, value) in d
    if value < minvalue
      minkey = key
      minvalue = value
    end
  end
  minkey
end
Run Code Online (Sandbox Code Playgroud)

...以及此代码:

function benchmark(n)
  d = Dict{Int, Int}(1 => 1)
  m1(d); m2(d); m3(d); m4(d); m5(d)

  while length(d) < n
    setindex!(d, rand(-n:n), rand(-n:n))
  end

  @time m1(d)
  @time m2(d)
  @time m3(d)
  @time m4(d)
end
Run Code Online (Sandbox Code Playgroud)

调用benchmark(10000000)会打印出这样的内容:

1.455388 seconds (30.00 M allocations: 457.748 MB, 4.30% gc time)
0.380472 seconds (6 allocations: 152.588 MB, 0.21% gc time)
0.982006 seconds (10.00 M allocations: 152.581 MB, 0.49% gc time)
0.204604 seconds
Run Code Online (Sandbox Code Playgroud)

从这一点我们可以看出m2(来自user3580870的答案)确实比我原来的解决方案快m1了大约3到4倍,并且使用更少的内存.这显然是由于函数调用开销,但也是由于λ表达式m1未被很好地优化的事实.我们可以通过定义一个像in m3这样的辅助函数来缓解第二个问题,这个函数优于m1,但不如m2.

但是,m2仍然可以分配O(n)内存,这是可以避免的:如果你真的需要效率,你应该使用像in m4这样的显式循环,它几乎不分配内存,也更快.


Dan*_*etz 6

另一种选择是:

collect(keys(d))[indmin(collect(values(d)))]
Run Code Online (Sandbox Code Playgroud)

这取决于密钥的属性和值未保证迭代器,但实际上对于日文N3 N4 N5工作(并保证OrderedDicts).像reduce答案一样,d必须是非空的.

为什么要提这个,当时reduce,几乎指甲呢?它快3到4倍(至少在我的电脑上)!

  • necroedit:从Julia 1.0开始,`indmin()`是`argmin()`。 (3认同)

小智 5

这是使用 Key 和 Value 查找 Min 的另一种方法

my_dict = Dict(1 => 20, 2 =>10)
Run Code Online (Sandbox Code Playgroud)

findmin(my_dict)输出如下

(10, 2)
Run Code Online (Sandbox Code Playgroud)

仅获得密钥使用

findmin(my_dict)[2]
Run Code Online (Sandbox Code Playgroud)

只获得价值使用

findmin(my_dict)[1]
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。