ShellRox
ShellRox

Reputation: 2602

Python: Finding nearest integer value to specific integer

I'm trying to add an algorithm to my script that would find the nearest integer value from few variables, so for example:

int = 700
value1 = 400
value2 = 500
value6 = 600

How can I make a script that gets value6 as the nearest value from all the value variables?

Upvotes: 4

Views: 2665

Answers (5)

My  name is Richard
My name is Richard

Reputation: 123

As a relative beginner to python I feel sure this could be improved. The other answers are great but only return the nearest value under the input when there are two values equally distant.

(above edited for clarity in response to Padraic Cunningham)

#!/usr/bin/python3

values = (100, 200, 300, 400, 500, 600, 700)
i = 245
nearest_under = min(values, key=lambda v: abs(v-i))
nearest_over = min(values, key=lambda v: abs(v-i) and v<i)

under_distance = i - nearest_under
over_distance = nearest_over - i 

if (under_distance == over_distance):
        nearest = (nearest_under, nearest_over)
elif under_distance < over_distance:
        nearest = (nearest_under, )
else:
        nearest = (nearest_over, )

print (nearest)

Upvotes: 2

Padraic Cunningham
Padraic Cunningham

Reputation: 180522

You can do it in log n time if you keep the numbers in order and bisect

i = 540
value1 = 400
value2 = 500
value6 = 600
lst = [value1, value2, value6]

from bisect import bisect
ind = bisect(lst, i, hi=len(lst) - 1)

print(min((lst[ind], lst[ind - 1]), key=lambda x: abs(x-i)))

Upvotes: 5

RoadRunner
RoadRunner

Reputation: 26335

You could also try this longer way, for learning purposes I guess:

    values = [400, 500, 600]
    i = 700

    candidates = []
    for value in values:
        candidates.append(abs(i-value))

    closest_index = candidates.index(min(candidates))
    print(values[closest_index])

Upvotes: 1

user2390182
user2390182

Reputation: 73498

Use min with an appropriate key function, e.g. the abs of the difference to i (which you really shouldn't name int):

i = 700  # don't shadow built-in name int
values = (value1, value2, ...)  # consider using a list/tuple from the beginning
nearest = min(values, key=lambda v: abs(i-v))

> nearest
600

Upvotes: 13

Daniel
Daniel

Reputation: 42778

You can use the min-function with key-argument:

values = [400, 500, 600]
int = 700
nearest = min(values, key=lambda v: abs(v-int))

Upvotes: 1

Related Questions