How can I find the closest, positive value, from a dictionary's item's keys? (Python)
Question:
Assuming I have a dictionary in this structure:
data = {
'111': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 301},
'112': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 302},
'113': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 377},
'114': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 311},
'115': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 314},
'116': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 306},
'117': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 387}
#...
}
Based on ‘c’ key, I’m looking for a way to return a dict item from which, a given input (e.g ‘312’), is the closest positive value in that key.
E.g:
input = 312
expected result:
>>> {'115': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 314}}
The script would ignore negative values (for example, item ‘114’ ‘c’ key is 311, which is closer to 312, but ignored since it’s less than the input number).
I’ve tried looking on google for ways to do this, but the only results I got were examples for the closest positive or negative, while the value I’m looking for has to be positive.
Answers:
You can use a generator expression to filter the keys with a c that is below the target and min
to find the closet key:
target = 312
closest_key_above = min((k for k, d in data.items() if d['c']>target),
key=lambda k: data[k]['c']-target)
Output:
'115'
To get the dictionary:
{closest_key_above: data[closest_key_above]}
# {'115': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 314}}
as a function
def find_closest(data, target):
key = min((k for k, d in data.items() if d['c']>target),
key=lambda k: data[k]['c']-target)
return {key: data[key]}
find_closest(data, 307)
# {'114': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 311}}
[ins] In [19]: data = {
...: '111': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 301},
...: '112': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 302},
...: '113': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 377},
...: '114': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 311},
...: '115': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 314},
...: '116': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 306},
...: '117': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 387},
...: }
[ins] In [20]: def closest_positive(inp, data):
...: data = {k: v for k, v in data.items() if v['c'] >= inp}
...: min_key = min(data, key = lambda k: data[k]['c'] - inp)
...: return {min_key: data[min_key]}
...:
[ins] In [21]: closest_positive(312, data)
Out[21]: {'115': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 314}}
The first line of the func drop all dict entries with the c
field smaller than the sought one.
The second once finds the "minimal" key in the rest of the dict by using a custom comparison function (the key = lambda ...
argument of min()
).
Code:
INPUT = int(input("Enter value:"))` #Get input
#count the difference between input and each c of dictionary
#mind not allowing smaller values to comes for calculation, lastly gettng min of list
nearst = min([data[d]['c'] for d in data if data[d]['c']>=INPUT], key=lambda x: x-INPUT)
#now loop over dictionary of that min in c
select that values
[data[d] for d in data if data[d]['c']==nearst]
Output:
[{'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 314}]
Assuming I have a dictionary in this structure:
data = {
'111': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 301},
'112': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 302},
'113': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 377},
'114': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 311},
'115': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 314},
'116': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 306},
'117': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 387}
#...
}
Based on ‘c’ key, I’m looking for a way to return a dict item from which, a given input (e.g ‘312’), is the closest positive value in that key.
E.g:
input = 312
expected result:
>>> {'115': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 314}}
The script would ignore negative values (for example, item ‘114’ ‘c’ key is 311, which is closer to 312, but ignored since it’s less than the input number).
I’ve tried looking on google for ways to do this, but the only results I got were examples for the closest positive or negative, while the value I’m looking for has to be positive.
You can use a generator expression to filter the keys with a c that is below the target and min
to find the closet key:
target = 312
closest_key_above = min((k for k, d in data.items() if d['c']>target),
key=lambda k: data[k]['c']-target)
Output:
'115'
To get the dictionary:
{closest_key_above: data[closest_key_above]}
# {'115': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 314}}
as a function
def find_closest(data, target):
key = min((k for k, d in data.items() if d['c']>target),
key=lambda k: data[k]['c']-target)
return {key: data[key]}
find_closest(data, 307)
# {'114': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 311}}
[ins] In [19]: data = {
...: '111': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 301},
...: '112': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 302},
...: '113': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 377},
...: '114': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 311},
...: '115': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 314},
...: '116': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 306},
...: '117': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 387},
...: }
[ins] In [20]: def closest_positive(inp, data):
...: data = {k: v for k, v in data.items() if v['c'] >= inp}
...: min_key = min(data, key = lambda k: data[k]['c'] - inp)
...: return {min_key: data[min_key]}
...:
[ins] In [21]: closest_positive(312, data)
Out[21]: {'115': {'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 314}}
The first line of the func drop all dict entries with the c
field smaller than the sought one.
The second once finds the "minimal" key in the rest of the dict by using a custom comparison function (the key = lambda ...
argument of min()
).
Code:
INPUT = int(input("Enter value:"))` #Get input
#count the difference between input and each c of dictionary
#mind not allowing smaller values to comes for calculation, lastly gettng min of list
nearst = min([data[d]['c'] for d in data if data[d]['c']>=INPUT], key=lambda x: x-INPUT)
#now loop over dictionary of that min in c
select that values
[data[d] for d in data if data[d]['c']==nearst]
Output:
[{'a': 'xxxxxx', 'b': 'xxxxxx', 'c': 314}]