Лучший способ проверить, больше ли значение, меньше или равно нулю в питоне

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

def set_colour(x, trigger=False):
    if x > 0.0:
        colour = 'green'
    elif x < 0.0:
        colour = 'red'
    else:
        colour = 'black'

    if trigger:
        colour = 'blue'

    return colour

Но мне это не нравится. Есть ли лучший способ, который будет более элегантным, эффективным и питонным? Я нашел этот пост очень интересным, но не могу использовать словари, так как я не проверяю статическое значение, а сравниваю его.

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

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

Я думаю, что я проверяю все соответствующие сообщения здесь, поэтому я надеюсь, что это не дубликат.

5 ответов

Решение

Это единственное изменение, которое я бы сделал:

def set_colour(x, trigger=False):
    if trigger:
        return 'blue'
    elif x > 0.0:
        return 'green'
    elif x < 0.0:
        return 'red'
    else:
        return 'black'

Вы могли бы использовать sign() поиск функции и индекса:

import math
def sign(v):
    return int(math.copysign(1,v))

def set_color(x, trigger=False):
    if trigger: return "blue"
    return ('red', 'black', 'green')[sign(x)+1]

Тем не менее, я не уверен, насколько это "лучше". "Умный"!= "Лучше" в обычном случае.

РЕДАКТИРОВАТЬ Альтернатива, которая позволяет легко расширить его для многих цветовых диапазонов:

colorRanges = (
    # start, color
    (-2, 'red'),
    (0, 'yellow'),
    (1, 'orange'),
)

def set_color(x, trigger=False):
    if trigger: return "blue"
    if x == 0.0: return 'black'

    for start, color in colorRanges:
        if x < start: return color

    return 'green'

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

Вы можете использовать вложенное условное выражение, как это

def set_colour(x, trigger=False):
    if trigger: return "blue"
    return "green" if x > 0.0 else "red" if x < 0.0 else "black"

assert set_colour(None, True)   == "blue"
assert set_colour(0.0, True)    == "blue"
assert set_colour(0.0, False)   == "black"
assert set_colour(0.01, False)  == "green"
assert set_colour(-0.01, False) == "red"

Это вполне читабельно и легко расширяется:)

def set_colour(x, trigger=False):
    color = 'black'
    color = 'green' if x > 0.0 else color
    color = 'red' if x < 0.0 else color
    color = 'blue' if trigger else color

    return color

Вы не можете бежать от того, что вам понадобятся некоторые условия. Однако вы можете перечислить ваши условия в списке и соответствующие цвета в другом списке, а затем вызвать условия. Таким образом, вы можете несколько отделить ваши условия от кода. Это потому, что функции являются первыми значениями класса в Python.

Вы можете сделать что-то вроде этого:

conditions =  [  
   lambda m: m <  -3,
   lambda m: m >= -3 and m < -2,
   lambda m: m >= -3 and m < -2,
   lambda m: m >= -2 and m <  0,
   lambda m: m ==  0,
   lambda m: m >=  0 and m <  1,
   lambda m: m >= 1 ]

colors = [
   'color1',
   'color2',
   'color3',
   'color4',
   'color5',
   'color6',
   'color7' ]

def colVal(m): return colors[ [c(m) for c in conditions].index(True) ]

Вот, colVal(-4) является 'color1', так далее...

Таким образом, вы можете добавлять свои conditions список, как вы хотите, и по-прежнему держать остальную часть кода в целости и сохранности. Это идея с тем, что вы можете сделать. Однако, как вы хотите отформатировать свой код, зависит от вас. Например, вы можете сделать

def set_colour(x, trigger=False): 
    if trigger: return 'someColor'
    else: return colVal(x)

Не уверен, что это то, что вы хотите.

Другие вопросы по тегам