Подтвердить что ты не робот

Поиск пользовательского словаря в Python

если у меня есть такой словарь

>>> d = {10: 3, 100: 2, 1000: 1}

Я могу напечатать что-то вроде:

>>> d.get(10), d.get(100), d.get(1000)
(3, 2, 1)

Хотя я хочу, чтобы, если данный ключ не найден, возвращается значение, соответствующее ближайшему ключу, для данного ключа:

>>> d.get(20), d.get(60), d.get(200)
(3, 2, 2)

Вместо этого результат в Python равен

(None, None, None)

Какой питоновский способ реализовать описанное мной поведение?

Спасибо

4b9b3361

Ответ 1

Вы можете получить из dict, чтобы изменить поведение метода get():

class ClosestDict(dict):
    def get(self, key):
        key = min(self.iterkeys(), key=lambda x: abs(x - key))
        return dict.get(self, key)

d = ClosestDict({10: 3, 100: 2, 1000: 1})
print (d.get(20), d.get(60), d.get(200))

печатает

(3, 2, 2)

Обратите внимание, что сложность get() больше не равна O (1), но O (n).

Ответ 2

bisect модуль позволяет быстро найти позицию вставки в отсортированном списке.

from bisect import bisect_right

def closest_matches(data, query):
    keys = sorted(data)
    return [data[i] for i in (min(map(abs, (keys[p-1], keys[p]))) for p in (bisect_right(keys, k) for k in query))]

>>> d = {10: 3, 100: 2, 1000: 1}
>>> closest_matches(d, [20, 60, 200])
[3, 3, 2]