julia - How to find the key for the min/max value of a Dict?
I want to find the key corresponding to the min or max value of a dictionary in julia. In Python I would to the following:
my_dict = {1:20, 2:10}
min(my_dict, my_dict.get)
Which would return the key 2.
How can I do the same in julia ?
my_dict = Dict(1=>20, 2=>10)
minimum(my_dict)
The latter returns 1=>20 instead of 2=>10 or 2.
dictionary julia
add a comment |
I want to find the key corresponding to the min or max value of a dictionary in julia. In Python I would to the following:
my_dict = {1:20, 2:10}
min(my_dict, my_dict.get)
Which would return the key 2.
How can I do the same in julia ?
my_dict = Dict(1=>20, 2=>10)
minimum(my_dict)
The latter returns 1=>20 instead of 2=>10 or 2.
dictionary julia
indmin()orfindmin()should work. Don't know whyminimum()does the wrong thing...
– daycaster
Oct 13 '15 at 20:59
findmindoesn't work actually; it even gives a strange result in this case:(1=>20,16)
– David P. Sanders
Oct 13 '15 at 21:06
@DavidP.Sanders Strange, I get (10,2).
– daycaster
Oct 13 '15 at 21:33
2
@daycasterminimumiteratesPairs, which compare lexicographically. Therefore, and because here the keys are unique,minimum(x)returns the containedPairwith the lowest key. Andindminreturns the index, which is different from the key.
– user4235730
Oct 13 '15 at 22:17
There is now an issue about this in the Julia repo: github.com/JuliaLang/julia/issues/14672
– Nicolas Payette
Apr 19 '17 at 14:44
add a comment |
I want to find the key corresponding to the min or max value of a dictionary in julia. In Python I would to the following:
my_dict = {1:20, 2:10}
min(my_dict, my_dict.get)
Which would return the key 2.
How can I do the same in julia ?
my_dict = Dict(1=>20, 2=>10)
minimum(my_dict)
The latter returns 1=>20 instead of 2=>10 or 2.
dictionary julia
I want to find the key corresponding to the min or max value of a dictionary in julia. In Python I would to the following:
my_dict = {1:20, 2:10}
min(my_dict, my_dict.get)
Which would return the key 2.
How can I do the same in julia ?
my_dict = Dict(1=>20, 2=>10)
minimum(my_dict)
The latter returns 1=>20 instead of 2=>10 or 2.
dictionary julia
dictionary julia
asked Oct 13 '15 at 20:21
tsschtssch
544618
544618
indmin()orfindmin()should work. Don't know whyminimum()does the wrong thing...
– daycaster
Oct 13 '15 at 20:59
findmindoesn't work actually; it even gives a strange result in this case:(1=>20,16)
– David P. Sanders
Oct 13 '15 at 21:06
@DavidP.Sanders Strange, I get (10,2).
– daycaster
Oct 13 '15 at 21:33
2
@daycasterminimumiteratesPairs, which compare lexicographically. Therefore, and because here the keys are unique,minimum(x)returns the containedPairwith the lowest key. Andindminreturns the index, which is different from the key.
– user4235730
Oct 13 '15 at 22:17
There is now an issue about this in the Julia repo: github.com/JuliaLang/julia/issues/14672
– Nicolas Payette
Apr 19 '17 at 14:44
add a comment |
indmin()orfindmin()should work. Don't know whyminimum()does the wrong thing...
– daycaster
Oct 13 '15 at 20:59
findmindoesn't work actually; it even gives a strange result in this case:(1=>20,16)
– David P. Sanders
Oct 13 '15 at 21:06
@DavidP.Sanders Strange, I get (10,2).
– daycaster
Oct 13 '15 at 21:33
2
@daycasterminimumiteratesPairs, which compare lexicographically. Therefore, and because here the keys are unique,minimum(x)returns the containedPairwith the lowest key. Andindminreturns the index, which is different from the key.
– user4235730
Oct 13 '15 at 22:17
There is now an issue about this in the Julia repo: github.com/JuliaLang/julia/issues/14672
– Nicolas Payette
Apr 19 '17 at 14:44
indmin() or findmin() should work. Don't know why minimum() does the wrong thing...– daycaster
Oct 13 '15 at 20:59
indmin() or findmin() should work. Don't know why minimum() does the wrong thing...– daycaster
Oct 13 '15 at 20:59
findmin doesn't work actually; it even gives a strange result in this case: (1=>20,16)– David P. Sanders
Oct 13 '15 at 21:06
findmin doesn't work actually; it even gives a strange result in this case: (1=>20,16)– David P. Sanders
Oct 13 '15 at 21:06
@DavidP.Sanders Strange, I get (10,2).
– daycaster
Oct 13 '15 at 21:33
@DavidP.Sanders Strange, I get (10,2).
– daycaster
Oct 13 '15 at 21:33
2
2
@daycaster
minimum iterates Pairs, which compare lexicographically. Therefore, and because here the keys are unique, minimum(x) returns the contained Pair with the lowest key. And indmin returns the index, which is different from the key.– user4235730
Oct 13 '15 at 22:17
@daycaster
minimum iterates Pairs, which compare lexicographically. Therefore, and because here the keys are unique, minimum(x) returns the contained Pair with the lowest key. And indmin returns the index, which is different from the key.– user4235730
Oct 13 '15 at 22:17
There is now an issue about this in the Julia repo: github.com/JuliaLang/julia/issues/14672
– Nicolas Payette
Apr 19 '17 at 14:44
There is now an issue about this in the Julia repo: github.com/JuliaLang/julia/issues/14672
– Nicolas Payette
Apr 19 '17 at 14:44
add a comment |
4 Answers
4
active
oldest
votes
another option is:
collect(keys(d))[indmin(collect(values(d)))]
it depends on properties of keys and values iterators which are not guaranteed, but in fact work for Dicts (and are guaranteed for OrderedDicts). like the reduce answer, d must be non-empty.
why mention this, when the reduce, pretty much nails it? it is 3 to 4 times faster (at least on my computer) !
1
I think it should be guaranteed that thekeysandvaluesiterator return elements in the same order. The order itself is undefined, but it'd be pretty crazy if they did something different from each other.
– Matt B.
Oct 14 '15 at 4:43
1
@MattB I don't think you should rely on this. As long as it's not documented, this is an implementation detail. But I agree that this should be guaranteed.
– user4235730
Oct 14 '15 at 19:15
1
Let's document it, then. Care to submit a pull request?
– Matt B.
Oct 14 '15 at 19:38
This can be written without thecollects, which will presumably be much faster:d.keys[indmin(values(d))]. However,d.keysis an internal data structure.
– David P. Sanders
Oct 15 '15 at 12:53
1
necroedit: As of Julia 1.0,indmin()isargmin().
– daycaster
Jan 8 at 22:53
|
show 1 more comment
You could use reduce like this, which will return the key of the first smallest value in d:
reduce((x, y) -> d[x] ≤ d[y] ? x : y, keys(d))
This only works for non-empty Dicts, though. (But the notion of the “key of the minimal value of no values” does not really make sense, so that case should usually be handled seperately anyway.)
Edit regarding efficiency.
Consider these definitions (none of which handle empty collections)...
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
...along with this code:
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
Calling benchmark(10000000) will print something like this:
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
From this we can see that m2 (from user3580870's answer) is indeed faster than my original solution m1 by a factor of around 3 to 4, and also uses less memory. This is appearently due to the function call overhead, but also the fact that the λ expression in m1 is not optimized very well. We can alleviate the second problem by defining a helper function like in m3, which is better than m1, but not as good as m2.
However, m2 still allocates O(n) memory, which can be avoided: If you really need the efficiency, you should use an explicit loop like in m4, which allocates almost no memory and is also faster.
a version without unicode and working for emptyDicts:reduce((x, y) -> (isa(x,Void) || (d[x] > d[y])) ? y : x, nothing, keys(d))
– Dan Getz
Oct 14 '15 at 3:40
1
Very nice comparison. I like the use ofnextto get the first value in the dictionary, even if the syntax is not elegant!
– David P. Sanders
Oct 15 '15 at 12:48
d.keys[indmin(values(d))]is very slightly slower than the explicit loop, but 3 times faster than the other short options. (However,d.keysis an internal data structure.)
– David P. Sanders
Oct 15 '15 at 13:01
Any idea, why isn'tm4part of any julia library?
– alvas
Mar 30 '17 at 8:14
add a comment |
If you only need the minimum value, you can use
minimum(values(my_dict))
If you need the key as well, I don't know a built-in function to do so, but you can easily write it yourself for numeric keys and values:
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)
1
(I have removed my other comment as it is now obsolete.) But doesn't this have type-stability problems as well, for instance ifd::Dict{Int, Int}? Isn't then the comparison betweenIntand eitherIntorFloat? Am I missing something?
– user4235730
Oct 14 '15 at 18:50
Ah, I see what you mean. I thought you meant that the output of the function was not type stable, but you mean thatminkeyandminvalchange type during the function. I'll give it another go...
– David P. Sanders
Oct 14 '15 at 19:03
Thanks. Fixed to usetypemax. This will work for any numeric types, but not e.g. for any kind ofStrings. It's surprisingly difficult to make this general! Thereducesolution does work for that case, though.
– David P. Sanders
Oct 14 '15 at 19:08
Agreed, this is why I only consider the non-empty case in my solution ;).
– user4235730
Oct 14 '15 at 19:18
add a comment |
Here is another way to find Min with Key and Value
my_dict = Dict(1 => 20, 2 =>10)
findmin(my_dict) gives the output as below
(10, 2)
to get only key use
findmin(my_dict)[2]
to get only value use
findmin(my_dict)[1]
Hope this helps.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f33111909%2fjulia-how-to-find-the-key-for-the-min-max-value-of-a-dict%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
another option is:
collect(keys(d))[indmin(collect(values(d)))]
it depends on properties of keys and values iterators which are not guaranteed, but in fact work for Dicts (and are guaranteed for OrderedDicts). like the reduce answer, d must be non-empty.
why mention this, when the reduce, pretty much nails it? it is 3 to 4 times faster (at least on my computer) !
1
I think it should be guaranteed that thekeysandvaluesiterator return elements in the same order. The order itself is undefined, but it'd be pretty crazy if they did something different from each other.
– Matt B.
Oct 14 '15 at 4:43
1
@MattB I don't think you should rely on this. As long as it's not documented, this is an implementation detail. But I agree that this should be guaranteed.
– user4235730
Oct 14 '15 at 19:15
1
Let's document it, then. Care to submit a pull request?
– Matt B.
Oct 14 '15 at 19:38
This can be written without thecollects, which will presumably be much faster:d.keys[indmin(values(d))]. However,d.keysis an internal data structure.
– David P. Sanders
Oct 15 '15 at 12:53
1
necroedit: As of Julia 1.0,indmin()isargmin().
– daycaster
Jan 8 at 22:53
|
show 1 more comment
another option is:
collect(keys(d))[indmin(collect(values(d)))]
it depends on properties of keys and values iterators which are not guaranteed, but in fact work for Dicts (and are guaranteed for OrderedDicts). like the reduce answer, d must be non-empty.
why mention this, when the reduce, pretty much nails it? it is 3 to 4 times faster (at least on my computer) !
1
I think it should be guaranteed that thekeysandvaluesiterator return elements in the same order. The order itself is undefined, but it'd be pretty crazy if they did something different from each other.
– Matt B.
Oct 14 '15 at 4:43
1
@MattB I don't think you should rely on this. As long as it's not documented, this is an implementation detail. But I agree that this should be guaranteed.
– user4235730
Oct 14 '15 at 19:15
1
Let's document it, then. Care to submit a pull request?
– Matt B.
Oct 14 '15 at 19:38
This can be written without thecollects, which will presumably be much faster:d.keys[indmin(values(d))]. However,d.keysis an internal data structure.
– David P. Sanders
Oct 15 '15 at 12:53
1
necroedit: As of Julia 1.0,indmin()isargmin().
– daycaster
Jan 8 at 22:53
|
show 1 more comment
another option is:
collect(keys(d))[indmin(collect(values(d)))]
it depends on properties of keys and values iterators which are not guaranteed, but in fact work for Dicts (and are guaranteed for OrderedDicts). like the reduce answer, d must be non-empty.
why mention this, when the reduce, pretty much nails it? it is 3 to 4 times faster (at least on my computer) !
another option is:
collect(keys(d))[indmin(collect(values(d)))]
it depends on properties of keys and values iterators which are not guaranteed, but in fact work for Dicts (and are guaranteed for OrderedDicts). like the reduce answer, d must be non-empty.
why mention this, when the reduce, pretty much nails it? it is 3 to 4 times faster (at least on my computer) !
answered Oct 14 '15 at 3:28
Dan GetzDan Getz
12.1k11332
12.1k11332
1
I think it should be guaranteed that thekeysandvaluesiterator return elements in the same order. The order itself is undefined, but it'd be pretty crazy if they did something different from each other.
– Matt B.
Oct 14 '15 at 4:43
1
@MattB I don't think you should rely on this. As long as it's not documented, this is an implementation detail. But I agree that this should be guaranteed.
– user4235730
Oct 14 '15 at 19:15
1
Let's document it, then. Care to submit a pull request?
– Matt B.
Oct 14 '15 at 19:38
This can be written without thecollects, which will presumably be much faster:d.keys[indmin(values(d))]. However,d.keysis an internal data structure.
– David P. Sanders
Oct 15 '15 at 12:53
1
necroedit: As of Julia 1.0,indmin()isargmin().
– daycaster
Jan 8 at 22:53
|
show 1 more comment
1
I think it should be guaranteed that thekeysandvaluesiterator return elements in the same order. The order itself is undefined, but it'd be pretty crazy if they did something different from each other.
– Matt B.
Oct 14 '15 at 4:43
1
@MattB I don't think you should rely on this. As long as it's not documented, this is an implementation detail. But I agree that this should be guaranteed.
– user4235730
Oct 14 '15 at 19:15
1
Let's document it, then. Care to submit a pull request?
– Matt B.
Oct 14 '15 at 19:38
This can be written without thecollects, which will presumably be much faster:d.keys[indmin(values(d))]. However,d.keysis an internal data structure.
– David P. Sanders
Oct 15 '15 at 12:53
1
necroedit: As of Julia 1.0,indmin()isargmin().
– daycaster
Jan 8 at 22:53
1
1
I think it should be guaranteed that the
keys and values iterator return elements in the same order. The order itself is undefined, but it'd be pretty crazy if they did something different from each other.– Matt B.
Oct 14 '15 at 4:43
I think it should be guaranteed that the
keys and values iterator return elements in the same order. The order itself is undefined, but it'd be pretty crazy if they did something different from each other.– Matt B.
Oct 14 '15 at 4:43
1
1
@MattB I don't think you should rely on this. As long as it's not documented, this is an implementation detail. But I agree that this should be guaranteed.
– user4235730
Oct 14 '15 at 19:15
@MattB I don't think you should rely on this. As long as it's not documented, this is an implementation detail. But I agree that this should be guaranteed.
– user4235730
Oct 14 '15 at 19:15
1
1
Let's document it, then. Care to submit a pull request?
– Matt B.
Oct 14 '15 at 19:38
Let's document it, then. Care to submit a pull request?
– Matt B.
Oct 14 '15 at 19:38
This can be written without the
collects, which will presumably be much faster: d.keys[indmin(values(d))]. However, d.keys is an internal data structure.– David P. Sanders
Oct 15 '15 at 12:53
This can be written without the
collects, which will presumably be much faster: d.keys[indmin(values(d))]. However, d.keys is an internal data structure.– David P. Sanders
Oct 15 '15 at 12:53
1
1
necroedit: As of Julia 1.0,
indmin() is argmin().– daycaster
Jan 8 at 22:53
necroedit: As of Julia 1.0,
indmin() is argmin().– daycaster
Jan 8 at 22:53
|
show 1 more comment
You could use reduce like this, which will return the key of the first smallest value in d:
reduce((x, y) -> d[x] ≤ d[y] ? x : y, keys(d))
This only works for non-empty Dicts, though. (But the notion of the “key of the minimal value of no values” does not really make sense, so that case should usually be handled seperately anyway.)
Edit regarding efficiency.
Consider these definitions (none of which handle empty collections)...
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
...along with this code:
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
Calling benchmark(10000000) will print something like this:
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
From this we can see that m2 (from user3580870's answer) is indeed faster than my original solution m1 by a factor of around 3 to 4, and also uses less memory. This is appearently due to the function call overhead, but also the fact that the λ expression in m1 is not optimized very well. We can alleviate the second problem by defining a helper function like in m3, which is better than m1, but not as good as m2.
However, m2 still allocates O(n) memory, which can be avoided: If you really need the efficiency, you should use an explicit loop like in m4, which allocates almost no memory and is also faster.
a version without unicode and working for emptyDicts:reduce((x, y) -> (isa(x,Void) || (d[x] > d[y])) ? y : x, nothing, keys(d))
– Dan Getz
Oct 14 '15 at 3:40
1
Very nice comparison. I like the use ofnextto get the first value in the dictionary, even if the syntax is not elegant!
– David P. Sanders
Oct 15 '15 at 12:48
d.keys[indmin(values(d))]is very slightly slower than the explicit loop, but 3 times faster than the other short options. (However,d.keysis an internal data structure.)
– David P. Sanders
Oct 15 '15 at 13:01
Any idea, why isn'tm4part of any julia library?
– alvas
Mar 30 '17 at 8:14
add a comment |
You could use reduce like this, which will return the key of the first smallest value in d:
reduce((x, y) -> d[x] ≤ d[y] ? x : y, keys(d))
This only works for non-empty Dicts, though. (But the notion of the “key of the minimal value of no values” does not really make sense, so that case should usually be handled seperately anyway.)
Edit regarding efficiency.
Consider these definitions (none of which handle empty collections)...
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
...along with this code:
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
Calling benchmark(10000000) will print something like this:
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
From this we can see that m2 (from user3580870's answer) is indeed faster than my original solution m1 by a factor of around 3 to 4, and also uses less memory. This is appearently due to the function call overhead, but also the fact that the λ expression in m1 is not optimized very well. We can alleviate the second problem by defining a helper function like in m3, which is better than m1, but not as good as m2.
However, m2 still allocates O(n) memory, which can be avoided: If you really need the efficiency, you should use an explicit loop like in m4, which allocates almost no memory and is also faster.
a version without unicode and working for emptyDicts:reduce((x, y) -> (isa(x,Void) || (d[x] > d[y])) ? y : x, nothing, keys(d))
– Dan Getz
Oct 14 '15 at 3:40
1
Very nice comparison. I like the use ofnextto get the first value in the dictionary, even if the syntax is not elegant!
– David P. Sanders
Oct 15 '15 at 12:48
d.keys[indmin(values(d))]is very slightly slower than the explicit loop, but 3 times faster than the other short options. (However,d.keysis an internal data structure.)
– David P. Sanders
Oct 15 '15 at 13:01
Any idea, why isn'tm4part of any julia library?
– alvas
Mar 30 '17 at 8:14
add a comment |
You could use reduce like this, which will return the key of the first smallest value in d:
reduce((x, y) -> d[x] ≤ d[y] ? x : y, keys(d))
This only works for non-empty Dicts, though. (But the notion of the “key of the minimal value of no values” does not really make sense, so that case should usually be handled seperately anyway.)
Edit regarding efficiency.
Consider these definitions (none of which handle empty collections)...
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
...along with this code:
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
Calling benchmark(10000000) will print something like this:
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
From this we can see that m2 (from user3580870's answer) is indeed faster than my original solution m1 by a factor of around 3 to 4, and also uses less memory. This is appearently due to the function call overhead, but also the fact that the λ expression in m1 is not optimized very well. We can alleviate the second problem by defining a helper function like in m3, which is better than m1, but not as good as m2.
However, m2 still allocates O(n) memory, which can be avoided: If you really need the efficiency, you should use an explicit loop like in m4, which allocates almost no memory and is also faster.
You could use reduce like this, which will return the key of the first smallest value in d:
reduce((x, y) -> d[x] ≤ d[y] ? x : y, keys(d))
This only works for non-empty Dicts, though. (But the notion of the “key of the minimal value of no values” does not really make sense, so that case should usually be handled seperately anyway.)
Edit regarding efficiency.
Consider these definitions (none of which handle empty collections)...
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
...along with this code:
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
Calling benchmark(10000000) will print something like this:
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
From this we can see that m2 (from user3580870's answer) is indeed faster than my original solution m1 by a factor of around 3 to 4, and also uses less memory. This is appearently due to the function call overhead, but also the fact that the λ expression in m1 is not optimized very well. We can alleviate the second problem by defining a helper function like in m3, which is better than m1, but not as good as m2.
However, m2 still allocates O(n) memory, which can be avoided: If you really need the efficiency, you should use an explicit loop like in m4, which allocates almost no memory and is also faster.
edited May 23 '17 at 11:46
Community♦
11
11
answered Oct 13 '15 at 22:00
user4235730user4235730
1,22611529
1,22611529
a version without unicode and working for emptyDicts:reduce((x, y) -> (isa(x,Void) || (d[x] > d[y])) ? y : x, nothing, keys(d))
– Dan Getz
Oct 14 '15 at 3:40
1
Very nice comparison. I like the use ofnextto get the first value in the dictionary, even if the syntax is not elegant!
– David P. Sanders
Oct 15 '15 at 12:48
d.keys[indmin(values(d))]is very slightly slower than the explicit loop, but 3 times faster than the other short options. (However,d.keysis an internal data structure.)
– David P. Sanders
Oct 15 '15 at 13:01
Any idea, why isn'tm4part of any julia library?
– alvas
Mar 30 '17 at 8:14
add a comment |
a version without unicode and working for emptyDicts:reduce((x, y) -> (isa(x,Void) || (d[x] > d[y])) ? y : x, nothing, keys(d))
– Dan Getz
Oct 14 '15 at 3:40
1
Very nice comparison. I like the use ofnextto get the first value in the dictionary, even if the syntax is not elegant!
– David P. Sanders
Oct 15 '15 at 12:48
d.keys[indmin(values(d))]is very slightly slower than the explicit loop, but 3 times faster than the other short options. (However,d.keysis an internal data structure.)
– David P. Sanders
Oct 15 '15 at 13:01
Any idea, why isn'tm4part of any julia library?
– alvas
Mar 30 '17 at 8:14
a version without unicode and working for empty
Dicts: reduce((x, y) -> (isa(x,Void) || (d[x] > d[y])) ? y : x, nothing, keys(d))– Dan Getz
Oct 14 '15 at 3:40
a version without unicode and working for empty
Dicts: reduce((x, y) -> (isa(x,Void) || (d[x] > d[y])) ? y : x, nothing, keys(d))– Dan Getz
Oct 14 '15 at 3:40
1
1
Very nice comparison. I like the use of
next to get the first value in the dictionary, even if the syntax is not elegant!– David P. Sanders
Oct 15 '15 at 12:48
Very nice comparison. I like the use of
next to get the first value in the dictionary, even if the syntax is not elegant!– David P. Sanders
Oct 15 '15 at 12:48
d.keys[indmin(values(d))] is very slightly slower than the explicit loop, but 3 times faster than the other short options. (However, d.keys is an internal data structure.)– David P. Sanders
Oct 15 '15 at 13:01
d.keys[indmin(values(d))] is very slightly slower than the explicit loop, but 3 times faster than the other short options. (However, d.keys is an internal data structure.)– David P. Sanders
Oct 15 '15 at 13:01
Any idea, why isn't
m4 part of any julia library?– alvas
Mar 30 '17 at 8:14
Any idea, why isn't
m4 part of any julia library?– alvas
Mar 30 '17 at 8:14
add a comment |
If you only need the minimum value, you can use
minimum(values(my_dict))
If you need the key as well, I don't know a built-in function to do so, but you can easily write it yourself for numeric keys and values:
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)
1
(I have removed my other comment as it is now obsolete.) But doesn't this have type-stability problems as well, for instance ifd::Dict{Int, Int}? Isn't then the comparison betweenIntand eitherIntorFloat? Am I missing something?
– user4235730
Oct 14 '15 at 18:50
Ah, I see what you mean. I thought you meant that the output of the function was not type stable, but you mean thatminkeyandminvalchange type during the function. I'll give it another go...
– David P. Sanders
Oct 14 '15 at 19:03
Thanks. Fixed to usetypemax. This will work for any numeric types, but not e.g. for any kind ofStrings. It's surprisingly difficult to make this general! Thereducesolution does work for that case, though.
– David P. Sanders
Oct 14 '15 at 19:08
Agreed, this is why I only consider the non-empty case in my solution ;).
– user4235730
Oct 14 '15 at 19:18
add a comment |
If you only need the minimum value, you can use
minimum(values(my_dict))
If you need the key as well, I don't know a built-in function to do so, but you can easily write it yourself for numeric keys and values:
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)
1
(I have removed my other comment as it is now obsolete.) But doesn't this have type-stability problems as well, for instance ifd::Dict{Int, Int}? Isn't then the comparison betweenIntand eitherIntorFloat? Am I missing something?
– user4235730
Oct 14 '15 at 18:50
Ah, I see what you mean. I thought you meant that the output of the function was not type stable, but you mean thatminkeyandminvalchange type during the function. I'll give it another go...
– David P. Sanders
Oct 14 '15 at 19:03
Thanks. Fixed to usetypemax. This will work for any numeric types, but not e.g. for any kind ofStrings. It's surprisingly difficult to make this general! Thereducesolution does work for that case, though.
– David P. Sanders
Oct 14 '15 at 19:08
Agreed, this is why I only consider the non-empty case in my solution ;).
– user4235730
Oct 14 '15 at 19:18
add a comment |
If you only need the minimum value, you can use
minimum(values(my_dict))
If you need the key as well, I don't know a built-in function to do so, but you can easily write it yourself for numeric keys and values:
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)
If you only need the minimum value, you can use
minimum(values(my_dict))
If you need the key as well, I don't know a built-in function to do so, but you can easily write it yourself for numeric keys and values:
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)
edited Oct 14 '15 at 19:05
answered Oct 13 '15 at 21:05
David P. SandersDavid P. Sanders
4,1961818
4,1961818
1
(I have removed my other comment as it is now obsolete.) But doesn't this have type-stability problems as well, for instance ifd::Dict{Int, Int}? Isn't then the comparison betweenIntand eitherIntorFloat? Am I missing something?
– user4235730
Oct 14 '15 at 18:50
Ah, I see what you mean. I thought you meant that the output of the function was not type stable, but you mean thatminkeyandminvalchange type during the function. I'll give it another go...
– David P. Sanders
Oct 14 '15 at 19:03
Thanks. Fixed to usetypemax. This will work for any numeric types, but not e.g. for any kind ofStrings. It's surprisingly difficult to make this general! Thereducesolution does work for that case, though.
– David P. Sanders
Oct 14 '15 at 19:08
Agreed, this is why I only consider the non-empty case in my solution ;).
– user4235730
Oct 14 '15 at 19:18
add a comment |
1
(I have removed my other comment as it is now obsolete.) But doesn't this have type-stability problems as well, for instance ifd::Dict{Int, Int}? Isn't then the comparison betweenIntand eitherIntorFloat? Am I missing something?
– user4235730
Oct 14 '15 at 18:50
Ah, I see what you mean. I thought you meant that the output of the function was not type stable, but you mean thatminkeyandminvalchange type during the function. I'll give it another go...
– David P. Sanders
Oct 14 '15 at 19:03
Thanks. Fixed to usetypemax. This will work for any numeric types, but not e.g. for any kind ofStrings. It's surprisingly difficult to make this general! Thereducesolution does work for that case, though.
– David P. Sanders
Oct 14 '15 at 19:08
Agreed, this is why I only consider the non-empty case in my solution ;).
– user4235730
Oct 14 '15 at 19:18
1
1
(I have removed my other comment as it is now obsolete.) But doesn't this have type-stability problems as well, for instance if
d::Dict{Int, Int}? Isn't then the comparison between Int and either Int or Float? Am I missing something?– user4235730
Oct 14 '15 at 18:50
(I have removed my other comment as it is now obsolete.) But doesn't this have type-stability problems as well, for instance if
d::Dict{Int, Int}? Isn't then the comparison between Int and either Int or Float? Am I missing something?– user4235730
Oct 14 '15 at 18:50
Ah, I see what you mean. I thought you meant that the output of the function was not type stable, but you mean that
minkey and minval change type during the function. I'll give it another go...– David P. Sanders
Oct 14 '15 at 19:03
Ah, I see what you mean. I thought you meant that the output of the function was not type stable, but you mean that
minkey and minval change type during the function. I'll give it another go...– David P. Sanders
Oct 14 '15 at 19:03
Thanks. Fixed to use
typemax. This will work for any numeric types, but not e.g. for any kind of Strings. It's surprisingly difficult to make this general! The reduce solution does work for that case, though.– David P. Sanders
Oct 14 '15 at 19:08
Thanks. Fixed to use
typemax. This will work for any numeric types, but not e.g. for any kind of Strings. It's surprisingly difficult to make this general! The reduce solution does work for that case, though.– David P. Sanders
Oct 14 '15 at 19:08
Agreed, this is why I only consider the non-empty case in my solution ;).
– user4235730
Oct 14 '15 at 19:18
Agreed, this is why I only consider the non-empty case in my solution ;).
– user4235730
Oct 14 '15 at 19:18
add a comment |
Here is another way to find Min with Key and Value
my_dict = Dict(1 => 20, 2 =>10)
findmin(my_dict) gives the output as below
(10, 2)
to get only key use
findmin(my_dict)[2]
to get only value use
findmin(my_dict)[1]
Hope this helps.
add a comment |
Here is another way to find Min with Key and Value
my_dict = Dict(1 => 20, 2 =>10)
findmin(my_dict) gives the output as below
(10, 2)
to get only key use
findmin(my_dict)[2]
to get only value use
findmin(my_dict)[1]
Hope this helps.
add a comment |
Here is another way to find Min with Key and Value
my_dict = Dict(1 => 20, 2 =>10)
findmin(my_dict) gives the output as below
(10, 2)
to get only key use
findmin(my_dict)[2]
to get only value use
findmin(my_dict)[1]
Hope this helps.
Here is another way to find Min with Key and Value
my_dict = Dict(1 => 20, 2 =>10)
findmin(my_dict) gives the output as below
(10, 2)
to get only key use
findmin(my_dict)[2]
to get only value use
findmin(my_dict)[1]
Hope this helps.
answered Nov 15 '18 at 3:26
RamaRama
112
112
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f33111909%2fjulia-how-to-find-the-key-for-the-min-max-value-of-a-dict%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
indmin()orfindmin()should work. Don't know whyminimum()does the wrong thing...– daycaster
Oct 13 '15 at 20:59
findmindoesn't work actually; it even gives a strange result in this case:(1=>20,16)– David P. Sanders
Oct 13 '15 at 21:06
@DavidP.Sanders Strange, I get (10,2).
– daycaster
Oct 13 '15 at 21:33
2
@daycaster
minimumiteratesPairs, which compare lexicographically. Therefore, and because here the keys are unique,minimum(x)returns the containedPairwith the lowest key. Andindminreturns the index, which is different from the key.– user4235730
Oct 13 '15 at 22:17
There is now an issue about this in the Julia repo: github.com/JuliaLang/julia/issues/14672
– Nicolas Payette
Apr 19 '17 at 14:44