Как в python реализовать проверку значения на то, к какому значению списка оно ближе

У меня есть список: [0.3, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.8, 0.85, 0.9, 1.0, 1.2, 1.3, 1.4, 1.5, 1.8, 2.0]

Как мне проверить значение полученное ранее на то, к какому из значений данного списка оно ближе? (Например значение 1.03)


Ответы (3 шт):

Автор решения: insolor

Считаем, что список всегда отсортированный, и число всегда попадает в диапазон между значениями первого и последнего элемента.

Задача решается с помощью бинарного поиска, в Python для этого уже есть стандартный модуль bisect.

С помощью bisect_left из модуля bisect находим индекс, куда нужно вставить искомое значение, чтобы список остался отсортированным. Дальше по этому индексу смотрим значения справа и слева, выбираем то, которое меньше отличается от искомого:

import bisect

s = [0.3, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.8, 0.85, 0.9, 1.0, 1.2, 1.3, 1.4, 1.5, 1.8, 2.0]
x = 1.03
i = bisect.bisect_left(s, x)

print(min(s[i-1], s[i], key=lambda y: (x - y) ** 2))
# 1.0
→ Ссылка
Автор решения: passant

На случай, если (судя по вопросу) вы еще не знакомы со сторонними библиотеками, а список может быть неотсортированным (о чем в вопросе - ни слова) - то вот так:

lt=[0.3, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.8, 0.85, 0.9, 1.0, 1.2, 1.3, 1.4, 1.5, 1.8, 2.0]

tl=1.03
im=0
ami=float("inf")
for i,a in enumerate(lt):
    if abs(tl-a)<ami:
        ami=abs(tl-a)
        im=i
print(lt[im])

Результат:

1.0

А можно и еще проще, в две строчки, вот так:

rs=list(map(lambda x:abs(x-tl),lt))
lt[rs.index(min(rs))]

с тем-же результатом.

→ Ссылка
Автор решения: CrazyElf

Так то вообще это делается указанием подходящего ключа для функции min:

lst = [0.3, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.8, 0.85, 0.9, 1.0, 1.2, 1.3, 1.4, 1.5, 1.8, 2.0]
z = 1.03
print(min(lst, key=lambda x: abs(x - z)))
# 1.0

Никакие дополнительные изыски не нужны. Ну, разве что кроме случая отсортированных заранее данных, где двоичный поиск очень ускорит дело (ответ insolor).

→ Ссылка