Python: отображение из интервалов в значения
Я рефакторинг функции, которая, учитывая ряд конечных точек, которые неявно определяют интервалы, проверяет, включен ли число в этот интервал, а затем возвращает соответствующий (не связанный каким-либо вычислимым образом). Код, который теперь обрабатывает работу:
if p <= 100: return 0 elif p > 100 and p <= 300: return 1 elif p > 300 and p <= 500: return 2 elif p > 500 and p <= 800: return 3 elif p > 800 and p <= 1000: return 4 elif p > 1000: return 5
Что ИМО довольно ужасно, и не хватает того, что и интервалы, и возвращаемые значения жестко запрограммированы. Конечно, любое использование любой структуры данных возможно.
- Как получить Pandas TimeSeries для пользовательских сеансов (с использованием Pandas или Numpy)
- Цикл с интервалом в любом направлении
- Python – подсчет частоты сообщений в диапазоне дат за каждый динамический интервал
- Интервал типа данных в Pandas – найдите середину, левый, центральный и т. Д.
- Как проверить, находится ли число в интервале
import bisect bisect.bisect_left([100,300,500,800,1000], p)
Вы можете попробовать:
def check_mapping(p): mapping = [(100, 0), (300, 1), (500, 2)] # Add all your values and returns here for check, value in mapping: if p <= check: return value print check_mapping(12) print check_mapping(101) print check_mapping(303)
производит:
0 1 2
Как всегда в Python, будут лучшие способы сделать это.
Это действительно ужасно. Без требования не иметь никакого жесткого кодирования, это должно было быть написано так:
if p <= 100: return 0 elif p <= 300: return 1 elif p <= 500: return 2 elif p <= 800: return 3 elif p <= 1000: return 4 else: return 5
Ниже приведены примеры создания функции поиска, как линейной, так и бинарного поиска, с выполнением требований без жесткого кодирования и нескольких проверок на две таблицы:
def make_linear_lookup(keys, values): assert sorted(keys) == keys assert len(values) == len(keys) + 1 def f(query): return values[sum(1 for key in keys if query > key)] return f import bisect def make_bisect_lookup(keys, values): assert sorted(keys) == keys assert len(values) == len(keys) + 1 def f(query): return values[bisect.bisect_left(keys, query)] return f
Попробуйте что-то вроде:
d = {(None,100): 0, (100,200): 1, ... (1000, None): 5} value = 300 # example value for k,v in d.items(): if (k[0] is None or value > k[0]) and (k[1] is None or value <= k[1]): return v
Другой путь …
def which(lst, p): return len([1 for el in lst if p > el]) lst = [100, 300, 500, 800, 1000] which(lst, 2) which(lst, 101) which(lst, 1001)
def which_interval(endpoints, number): for n, endpoint in enumerate(endpoints): if number <= endpoint: return n previous = endpoint return n + 1
Передайте конечные точки в виде списка в endpoints
, например:
which_interval([100, 300, 500, 800, 1000], 5)
Редактировать:
Вышеупомянутый – линейный поиск. Ответ Гленна Мейнарда будет иметь лучшую производительность, поскольку он использует алгоритм деления пополам.