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
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
2
@daycasterminimum
iteratesPair
s, which compare lexicographically. Therefore, and because here the keys are unique,minimum(x)
returns the containedPair
with the lowest key. Andindmin
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
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
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
2
@daycasterminimum
iteratesPair
s, which compare lexicographically. Therefore, and because here the keys are unique,minimum(x)
returns the containedPair
with the lowest key. Andindmin
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
add a comment |
indmin()
orfindmin()
should work. Don't know whyminimum()
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
@DavidP.Sanders Strange, I get (10,2).
– daycaster
Oct 13 '15 at 21:33
2
@daycasterminimum
iteratesPair
s, which compare lexicographically. Therefore, and because here the keys are unique,minimum(x)
returns the containedPair
with the lowest key. Andindmin
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
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 Pair
s, 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 Pair
s, 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 thekeys
andvalues
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
@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 thecollect
s, 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
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 Dict
s, 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 ofnext
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
Any idea, why isn'tm4
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 betweenInt
and eitherInt
orFloat
? 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 thatminkey
andminval
change 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 ofString
s. It's surprisingly difficult to make this general! Thereduce
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
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 thekeys
andvalues
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
@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 thecollect
s, 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
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 thekeys
andvalues
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
@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 thecollect
s, 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
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 thekeys
andvalues
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
@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 thecollect
s, 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
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 thekeys
andvalues
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
@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 thecollect
s, 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
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
collect
s, 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
collect
s, 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 Dict
s, 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 ofnext
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
Any idea, why isn'tm4
part 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 Dict
s, 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 ofnext
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
Any idea, why isn'tm4
part 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 Dict
s, 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 Dict
s, 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 ofnext
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
Any idea, why isn'tm4
part 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 ofnext
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
Any idea, why isn'tm4
part 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 betweenInt
and eitherInt
orFloat
? 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 thatminkey
andminval
change 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 ofString
s. It's surprisingly difficult to make this general! Thereduce
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
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 betweenInt
and eitherInt
orFloat
? 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 thatminkey
andminval
change 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 ofString
s. It's surprisingly difficult to make this general! Thereduce
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
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 betweenInt
and eitherInt
orFloat
? 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 thatminkey
andminval
change 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 ofString
s. It's surprisingly difficult to make this general! Thereduce
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
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 betweenInt
and eitherInt
orFloat
? 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 thatminkey
andminval
change 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 ofString
s. It's surprisingly difficult to make this general! Thereduce
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
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 String
s. 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 String
s. 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
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
2
@daycaster
minimum
iteratesPair
s, which compare lexicographically. Therefore, and because here the keys are unique,minimum(x)
returns the containedPair
with the lowest key. Andindmin
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