dic = {'a':4, 'b':5, 'cd':5 }
I'm trying to find:
- highest value (search for the highest value first =>
b
,cd
) - longest key (then search for the longest key =>
'cd'
)
I use the following code:
max_val = dic[max(dic, key=dic.get)]
maxDicVal = dict(filter(lambda x: x[1] == max_val, dic.items()))
maxDicKey = max(maxDicVal, key=len)
Is there any better way to achieve this?
Thanks.
CodePudding user response:
You can then sort the dictionary items based on the value descending followed by the length of the key descending. For example:
items = sorted(dic.items(), key=lambda v:(v[1], len(v[0])), reverse=True)
Output:
[('cd', 5), ('b', 5), ('a', 4)]
The maxDicKey
is then items[0][0]
i.e. cd
CodePudding user response:
A big improvement
We really should try to do everything in one pass. The downside is that there is more code. The following stores the first key in dic
in cur
, then iterates through dic
, starting from the second key, updating cur
if we find a value that is greater than the value associated with the key cur
or if we find a key, value pair with value equal to the value associated with the key cur
and the length of the key is greater than the length of cur
.
it = iter(dic)
cur = next(it) # the first key
for key in it: # iterate thr keys of dic, starting from second
if dic[key] > dic[cur] or (dic[key] == dic[cur] and len(key) > len(cur)):
cur = key
print(cur)
A smaller improvement
max_value = max(dic.values())
a = max((k for k in dic if dic[k] == max_value), key = len)
(k for k in dic if dic[k] == max_value)
is a generator that yields keys in dic
such that its value is equal to the maximum value. max(..., key = len)
then chooses the largest string amongst those keys.
The above is faster than this one-liner as the above caches max(dic.values())
:
a = max((k for k in dic if dic[k] == max(dic.values())), key = len)
Timings
# EBDS
1.19 µs ± 3.26 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
# oda (a smaller improvement)
759 ns ± 4.12 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
# oda (a big improvement)
304 ns ± 0.953 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
# Nick
648 ns ± 1.36 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)