以编程方式生成elif elif elif else

时间:2016-09-03 22:52:50

标签: python if-statement dry

我想浓缩一些看起来像这样的湿代码:

if slips[i] < 3000:
    ac.setBackgroundColor(wheel['slip'], 0, 0, 0)
    # setBackgroundOpacity deliberately omitted here
elif slips[i] < 3700:
    ac.setBackgroundColor(wheel['slip'], .2, .4, .2)
    ac.setBackgroundOpacity(wheel['slip'], 1)
elif slips[i] < 4100:
    ac.setBackgroundColor(wheel['slip'], 0, 1, 0)
    ac.setBackgroundOpacity(wheel['slip'], 1)
elif slips[i] < 4500:
    ac.setBackgroundColor(wheel['slip'], 0, 0, 1)
    ac.setBackgroundOpacity(wheel['slip'], 1)
else:
    ac.setBackgroundColor(wheel['slip'], 1, 0, 0)
    ac.setBackgroundOpacity(wheel['slip'], 1)

每次重复这段代码时,唯一改变的是背景画布(在这种情况下为wheel['slip']),以及if ifif else中的数字。

我首先想到的就是制作一些可以像这样使用的东西:

if_replacer(wheel['slip'], slips[i], 3000, 3700, 4100, 4500)

def if_replacer(canvas, value, *args):
    # idunno

我的问题是,如何以编程方式生成if elif else?我知道我可以像这样硬编码:

def if_replacer(canvas, value, c1, c2, c3, c4):
    if value < c1:
        ac.setBackgroundColor(canvas, 0, 0, 0)
        return
    elif value < c2:
        ac.setBackgroundColor(canvas, .2, .4, .2)
    elif value < c3:
        ac.setBackgroundColor(canvas, 0, 1, 0)
    elif value < c4:
        ac.setBackgroundColor(canvas, 0, 0, 1)
    else:
        ac.setBackgroundColor(canvas, 1, 0, 0)
    ac.setBackgroundOpacity(canvas, 1)

但我很感兴趣,如果有简洁的Pythonic方法来实现这一点。

编辑:很多优秀的答案,但是我只能将其中一个标记为已被接受(尽管所有有效的解决方案都被赞成)。我接受了我在我的代码中实现的答案,但是对于遇到这个问题的其他人来说,看看其他解决方案,他们都非常出色。并且,感谢所有写过答案的人。

5 个答案:

答案 0 :(得分:2)

这是一个可能的解决方案。

def least_bound_index(value, bounds):
    """return the least index such that value < bounds[i], or else len(bounds)""" 
    for i, b in enumerate(bounds):
        if value < b:
            return i
    return i+1

bounds = [3000, 3700, 4100, 4500]
bgcolors = [(0, 0, 0), (.2, .4, .2), (0, 1, 0), (0, 0, 1), (1, 0, 0)]

i = least_bound_index(slips[i], bounds)
ac.setBackgroundColor(wheel['slip'], *bgcolors[i])
if i > 0:
    ac.setBackgroundOpacity(wheel['slip'], 1)

请注意,least_bound_index也可以称为index_between,因为您可以想象数字行上的[a,b,c,d],它会告诉您这些选择的价值在哪里:

  a   b   c   d
^   ^   ^   ^   ^
0   1   2   3   4

答案 1 :(得分:2)

如果错误地省略了'setBackgroundOpacity',或者如果第一种情况中也包含它并不重要,那么这是您可能正在寻找的解决方案:

while ( (scanf ("%d", &number) ) == 0) {
     printf("Entered value is not integer");
}

编辑:看到有关setBackgroundOpacity函数的评论

Edit2:修正了拼写错误并为10 ** 10

添加了替代解决方案
color_map = [ (3000, 0, 0, 0), 
              (3700, .2, .4, .2), 
              (4100, 0, 1, 0), 
              (4500, 0, 0, 1), 
              (10**10, 1, 0, 0) ]

for i, (c, r, g, b) in enumerate(color_map):
    if value < c:
        ac.setBackgroundColor(wheel['slip'], r, g, b)
        if i > 0:
            ac.setBackgroundOpacity(wheel['slip'], 1)
        break

答案 2 :(得分:1)

c = [[0,0,0],[.2,.4,.2],[0,1,0],[0,0,1]]
threshold = [3000,3700,4100,4500]
if slips[i] >= 4500:
    ac.setBackgroundColor(wheel['slip'],1,0,0)
else:
    for x in range(4):
        if slips[i] < threshold[x]:
            ac.setBackgroundColor(wheel['slip'],c[x][0],c[x][1],c[x][2])
            break
if slips[i] >= 3000:
    ac.setBackgroundOpacity(wheel['slip'], 1)

这是另一种选择,但我个人更喜欢@ mpurg的答案。

答案 3 :(得分:1)

我接受它(未经测试的实际ac...次调用):

from functools import partial

mapping = [
    (3000, (0, 0, 0), None),
    (3700, (.2, .4, .2), 1),
    (4100, (0, 1, 0), 1),
    (4500, (0, 0, 1), 1),
    (float('inf'), (1, 0, 0), 1)
]

def if_replacer(canvas, value, mapping):
    set_color = partial(ac.setBackgroundColor, canvas)
    set_opacity = partial(ac.setBackgroundOpacity, canvas)
    for limit, vals, opacity in lookup:
        if value < limit:
            set_color(*vals)
            if opacity is not None:
                set_opacity(opacity)
            break

然后,如果由于某种原因你必须选择新的范围,那么你可以做类似的事情:

from bisect import insort_left
insort_left(mapping, (4300, (1, 1, 1), 0))

mapping更新为:

[(3000, (0, 0, 0), None),
 (3700, (0.2, 0.4, 0.2), 1),
 (4100, (0, 1, 0), 1),
 (4300, (1, 1, 1), 0),
 (4500, (0, 0, 1), 1),
 (inf, (1, 0, 0), 1)]

答案 4 :(得分:0)

def problem1_5(age):
    """Prints according to ages"""
    if age(1<7):
        print("Have a glass of milk")
    elif age(7<21):
        print("Have a cake")
    elif age>21:
        print("Have a martini")
    else:
        print(end='')