在Python中更好的方法判断值是否大于、小于或等于零

3 投票
5 回答
6467 浏览
提问于 2025-04-18 03:05

我有一个函数,它会检查一个值是大于、小于还是等于零,然后根据结果返回三种颜色中的一种。如果某个特定的属性存在,它就不会返回这三种颜色中的任何一种,而是返回一种单独的第四种颜色。我是这样解决这个问题的:

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

不过我不太喜欢这个方法。有没有更优雅、更高效、更符合Python风格的做法呢?我发现这篇帖子很有意思,但我不能用字典,因为我不是在检查一个固定的值,而是在比较值。

有没有可能定义一个变量,用来测试所有大于零的数字,以便使用字典的解决方案?也许可以用lambda?我尝试了一些方法,但没有找到好的解决方案。

目前我这个解决方案可能还算可以,但将来可能会增加更多颜色,比如小于-1.0、-2.0,或者大于1.0、2.0等。到时候代码只会越来越长,而我觉得这个问题可以用更优雅的方式解决。

我想我已经查看了所有相关的帖子,所以希望这不是重复的问题。

5 个回答

1

这段代码非常容易读懂,而且也很容易扩展:)

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
1

你可以使用嵌套的条件表达式,像这样

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"
1

你无法避免需要一些条件这一事实。不过,你可以把条件放在一个列表里,把对应的颜色放在另一个列表里,然后调用这些条件。这样,你就可以把条件和代码分开一些。这是因为在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)

不过我不确定这是否是你想要的。

4

你可以使用一个 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'

这个方法让你可以轻松定义颜色范围,但我还没有找到一个好的办法来更好地处理一些特殊情况。

7

我只会做这个改动:

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'

撰写回答