Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: find closest key in a dictionary from the given input key

Tags:

I have a data in form a dictionary.. NOw I take the input from the user and it can be anything.. And I am trying to do the following. If the key exists then cool.. fetch the value from the dictionary. if not, then fetch the nearest (in numeric sense). For example..if the input key is 200 and the keys are like :....

197,202,208... 

Then probably 202 is the closest key to 200.. Now, from algorithm point of view. its straight forward.. but is there a pythonic way to do this? Thanks

like image 824
frazman Avatar asked Oct 28 '11 20:10

frazman


2 Answers

This issue is made a lot harder by dict keys being in no particular order. If you can play with how you make the dict so they are in order (like your example) and use python >= 2.7 you can use OrderedDict and bisect to make this lightning fast.

import collections a = collections.OrderedDict() for i in range(100):     a[i] = i  import bisect ind = bisect.bisect_left(a.keys(), 45.3) 

Then you only have to check element ind and ind-1 to see which is closer, thus making a lot fewer calculations.


As pointed out below by Steven G, in Python3 the .keys() is not just a list and must be changed into one.

bisect.bisect_left(list(a.keys()), 45.3) 
like image 119
Brian Larsen Avatar answered Oct 12 '22 20:10

Brian Larsen


here's your function on one line:

data.get(num, data[min(data.keys(), key=lambda k: abs(k-num))]) 

edit: to not evaluate the min when the key is in the dict use:

data[num] if num in data else data[min(data.keys(), key=lambda k: abs(k-num))] 

or if all values in data evaluate to True you can use:

data.get(num) or data[min(data.keys(), key=lambda k: abs(k-num))] 
like image 42
Will Avatar answered Oct 12 '22 21:10

Will