#python
Вопрос:
я получил этот код, и мне нужно найти более читаемый и функциональный способ его написания, в этом проекте используется python 3.6
level_buy = 62 level=0 a1= range(1,10) a2= range(12,16) a3= range(18,29) a4= range(34,46) a5= range(54,63) a6= range(73,85) b1= range(10,12) b2= range(16,18) b3= range(29,34) b4= range(46,54) b5= range(63,73) if recomendation=='buy': if level_buy in a1: level=a2[0] if level_buy in b1: level=b2[0] if level_buy in a2: level=a3[0] if level_buy in b2: level=b3[0] if level_buy in a3: level=a4[0] if level_buy in b3: level=b4[0] if level_buy in a4: level=a5[0] if level_buy in b4: level=b5[0] if level_buy in a5: level=a6[0] if level_buy in b5: level=85 if level_buy in a6: level=85
Это должно вернуться, если level_buy находится в одном из заданных диапазонов, установите level = первое число в следующем диапазоне. Пример: level_buy=62, если я вызову уровень, должно быть возвращено 73
Заранее спасибо
Комментарии:
1. Как работают эти диапазоны? Почему переход с 1-10 на 12-16, а затем на 18-29?
2. Нет, но python 3.10 добавляет операторы соответствия для структур, подобных регистру.
3. По-моему, это выглядит довольно читабельно. Что с ним не так? Может быть, включите его в функцию, если хотите, чтобы он выглядел красивее.
4. Прежде всего, вы можете сделать эти инструкции elif, чтобы ваша программа работала возможно быстрее
5. @eagle33322 не вижу, как это было бы более читабельно, и я все равно не уверен, что это хороший вариант использования для сопоставления шаблонов.
Ответ №1:
Я полагаю, что вы могли бы заменить свою серию if
утверждений for
циклом для перебора ваших диапазонов.
ranges = (a1, b1, a2, b2, a3, b3, a4, b4, a5, b5) if recomendation == 'buy': for i, ab in enumerate(ranges[:-1]): if level_buy in ab: level = ranges[i 1][0] break else: level=85 print(level)
Комментарии:
1. уровень присваивается первому элементу следующего диапазона, а не диапазону, в котором он был найден.
2. Хорошо подмечено, спасибо. Это должно все исправить.
3. Кроме того, это
else
должно быть прикреплено кif
, или кfor
?4.
for
, но они функционально эквивалентны. Я все равно это исправил.
Ответ №2:
Вы могли бы сохранить диапазоны в списке вместо множества отдельных переменных:
ranges = [ range(1,10), range(12,16), range(18,29), ... ]
А затем вы можете повторить список:
for pos, r in enumerate(ranges): if level_buy in r: level = ranges[pos 1][0]
Если вы не хотите, чтобы последний a
диапазон соединялся с первым b
диапазоном, вы, возможно, могли бы сохранить два списка.
Ответ №3:
Предположения: ни один из диапазонов не перекрывается и что уровень всегда является верхней границей следующего последовательного диапазона. Подход состоит в том, чтобы отфильтровать нижние уровни, а затем пропустить один, чтобы получить правильное число.
level_buy = 62 thresholds = [1,10,12,16,18,29,34,46,54,63,73,85] selection = [t for t in thresholds if level_buy lt; t] level = selection[1] if len(selection) gt; 1 else 85
Ответ №4:
Ты пропустил объявление recommendation
. Но вот альтернатива вашему сценарию, если вы хотите сохранить логику, аналогичную той, которую вы опубликовали:
from itertools import chain recommendation = "buy" level_buy = 62 level = 0 a1 = range(1, 10) a2 = range(12, 16) a3 = range(18, 29) a4 = range(34, 46) a5 = range(54, 63) a6 = range(73, 85) b1 = range(10, 12) b2 = range(16, 18) b3 = range(29, 34) b4 = range(46, 54) b5 = range(63, 73) a_ranges = [a1, a2, a3, a4, a5, a6] b_ranges = [b1, b2, b3, b4, b5] combined_ranges = chain.from_iterable(zip(a_ranges, b_ranges)) if recommendation == "buy": for range_ in combined_ranges: if level_buy in range_: level = range_[0] break print(level)
Ответ №5:
Если вы звоните по этому номеру много раз, и у вас не слишком много диапазонов для установки, и вы хотите, чтобы для таблицы поиска требовалась предварительная стоимость и память, вы можете предварительно обработать это:
from itertools import chain level_sets = [(range(1,10), 12), (range(12,16), 18), (range(18,29), 34), (range(34,46), 54), (range(54,63), 73), (range(73,85), 85), (range(10,12), 16), (range(16,18), 29), (range(29,34), 46), (range(46,54), 63), (range(63,73), 85)] levels = {l: s for l, s in chain(*([(k, v) for k in r] for r, v in level_sets))} ... for buy in recommendation_list: level = levels.get(level_buy)
Это в основном говорит о том, что для каждого целого числа у вас есть какой-то уровень, на который он будет указывать. Преимущество этого способа заключается в том, что каждый раз, когда вам нужно получить уровень для покупки уровня, это операция O(1) — поэтому, если у вас было большое количество рекомендаций, которые нужно сделать, это будет иметь небольшую первоначальную стоимость (построение таблицы поиска), а затем очень небольшую добавочную стоимость (поиск покупки уровня). Это контрастирует с отсутствием первоначальных затрат и стоимостью O(n) каждый раз, когда n
у вас есть количество диапазонов.