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

时间:2015-10-13 20:21:20

标签: dictionary julia

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

my_dict = {1:20, 2:10}
min(my_dict, my_dict.get)

哪会返回密钥2.

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

my_dict = Dict(1=>20, 2=>10)
minimum(my_dict)

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

4 个答案:

答案 0 :(得分:8)

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

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

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

编辑效率。

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

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

...以及此代码:

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

调用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

由此我们可以看到m2(来自user3580870's answer)确实比原始解决方案m1快了大约3到4倍,并且还使用了更少的内存。这显然是由于函数调用开销,而且还因为m1中的λ表达式未得到很好的优化。我们可以通过定义m3中的辅助函数来缓解第二个问题,该函数优于m1,但不如m2

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

答案 1 :(得分:6)

另一种选择是:

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

它取决于键和迭代器的属性,这些属性不能得到保证,但实际上适用于Dicts(并且 保证为OrderedDicts)。与reduce答案一样,d必须为非空。

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

答案 2 :(得分:3)

如果您只需要最小值,则可以使用

minimum(values(my_dict))

如果您还需要密钥,我不知道这样做的内置函数,但您可以轻松地自己编写数字键和值:

function find_min_key{K,V}(d::Dict{K,V})

    minkey = typemax(K)
    minval = typemax(V)

    for key in keys(d)
        if d[key] < minval
            minkey = key
            minval = d[key]
        end
    end

    minkey => minval
end

my_dict = Dict(1=>20, 2=>10)

find_min_key(my_dict)

答案 3 :(得分:1)

这是用键和值查找最小值的另一种方法

my_dict = Dict(1 => 20, 2 =>10)

findmin(my_dict)给出如下输出

(10, 2)

仅获得密钥使用

findmin(my_dict)[2]

仅获得价值使用

findmin(my_dict)[1]

希望这会有所帮助。