Как упростить повторяющуюся функцию - PullRequest
3 голосов
/ 27 сентября 2019

Можно ли придумать, как упростить эту функцию?Я нахожу многое из этого довольно повторяющимся, но мне трудно думать о том, как сделать его более питоническим или чище.Относительно новичок в Python, поэтому я буду признателен за любые рекомендации.

def colorize(n):
    if n in range(0, 10):
        return selection[-1]
    elif n in range(10, 20):
        return selection[-2]
    elif n in range(20, 30):
        return selection[-3]
    elif n in range(30, 40):
        return selection[-4]
    elif n in range(40, 50):
        return selection[-5]
    elif n in range(50, 60):
        return selection[-6]
    elif n in range(60, 70):
        return selection[-7]
    elif n in range(70, 80):
        return selection[-8]
    elif n in range(80, 90):
        return selection[-9]
    elif n in range(90, 100):
        return selection[-10]
    else:
        return None

Ответы [ 5 ]

3 голосов
/ 27 сентября 2019

Если у вас есть куча повторяющихся кодов, и вам трудно понять, как удалить повторение, хорошим трюком является постепенное изменение фрагментов, чтобы они постепенно начали напоминать друг друга.Если вы все сделаете правильно, вы можете сделать так, чтобы они точно соответствовали друг другу.

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

Позвольте мне показать вам, что я имею в виду.


Шаг 1: Поверните все elif s в прямые if s и удалите else.Это делает их более очевидно одинаковыми, и вы должны видеть, что это не меняет поведение кода.

if n in range(0, 10):
    return selection[-1]
if n in range(10, 20):
    return selection[-2]
if n in range(20, 30):
    return selection[-3]
if n in range(30, 40):
    return selection[-4]
if n in range(40, 50):
    return selection[-5]
if n in range(50, 60):
    return selection[-6]
if n in range(60, 70):
    return selection[-7]
if n in range(70, 80):
    return selection[-8]
if n in range(80, 90):
    return selection[-9]
if n in range(90, 100):
    return selection[-10]

return None

Шаг 2: Рассчитайте числа на основе некоторых общихстоимость.Мы хотим извлечь новую переменную i так, чтобы каждый случай стал буквально идентичным остальному.Если мы установим i на 1, затем на 2, затем на 3 и т. Д., Мы можем сделать это.

Давайте рассмотрим первый случай:

if n in range(0, 10):
    return selection[-1]

Если i равно 1, тогда 10 равно i*10, -1 равно -i, а 0 равно (i-1)*10.

i = 1
if n in range((i-1)*10, i*10):
    return selection[-i]

Мы можем сделать то же самое для второго случая.

if n in range(10, 20):
    return selection[-2]

Те же формулы работают.Все, что нам нужно сделать, это изменить i на 2!

i = 2
if n in range((i-1)*10, i*10):
    return selection[-i]

Сполоснуть и повторить 10 раз, и мы получим эту красоту:

i = 1
if n in range((i-1)*10, i*10):
    return selection[-i]
i = 2
if n in range((i-1)*10, i*10):
    return selection[-i]
i = 3
if n in range((i-1)*10, i*10):
    return selection[-i]
i = 4
if n in range((i-1)*10, i*10):
    return selection[-i]
i = 5
if n in range((i-1)*10, i*10):
    return selection[-i]
i = 6
if n in range((i-1)*10, i*10):
    return selection[-i]
i = 7
if n in range((i-1)*10, i*10):
    return selection[-i]
i = 8
if n in range((i-1)*10, i*10):
    return selection[-i]
i = 9
if n in range((i-1)*10, i*10):
    return selection[-i]
i = 10
if n in range((i-1)*10, i*10):
    return selection[-i]

return None

Шаг 3: Теперь, когда у нас есть 10 одинаковых if операторов, должно быть понятно, как все это превратить в цикл.Цикл от i=1 до i=10 и мы его получили.

for i in range(1, 11):
    if n in range((i-1)*10, i*10):
        return selection[-i]

return None

Вот и мы!Все повторяющиеся вещи пропали.


Шаг 4: Если вы хотите пойти еще дальше, вы можете попытаться вычислить значение i, которое соответствует nвместо того, чтобы использовать подход угадывания и проверки выше.Я оставлю это как упражнение для вас (или для других ответов).Это хорошая оптимизация, но она находится в другой лиге, чем тот тип рефакторинга, который я только что изложил здесь.

3 голосов
/ 27 сентября 2019

Чтобы получить 1 для диапазона от 0 до 10 и 2 для диапазона от 10 до 20, вы можете использовать целочисленное деление в Python 3.

x = n // 10 + 1

Затем вы можете отрицать это и использовать это для индексации

def colorize(n):
    if 0 <= n < 100:
        return selection[-(n // 10 + 1)]

Если вы не возвращаете ничего из функции, которую она возвращает None, вам не нужно явно возвращать ее

0 голосов
/ 27 сентября 2019

Вы можете попробовать что-то вроде этого,

def colorize(n):
    if n in range(0,100):
        return selection[-1*(n//10+1)]
0 голосов
/ 27 сентября 2019

Попробуйте это:

def colorize(n):
    for i in range(0,11):
        if n in range((i*10),(i*10)+10):
            return selection[-(i+1)]
0 голосов
/ 27 сентября 2019

Очевидный способ упростить повторяющуюся функцию - использовать цикл:

def colorize(n):
    for i in range(0,10):
        if n in range(i*10, (i+1)*10):
            return selection[-i+1]
    return None

Я уверен, что есть лучший способ упростить вашу конкретную задачу, но цикл - это общий шаблон, который вы должны сохранитьв виду, когда вы видите этот вид повторяющегося кода.

...