Python 以编程方式生成if elif elif else
我想浓缩一些湿代码,如下所示:Python 以编程方式生成if elif elif else,python,if-statement,dry,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(wh
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)
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)
def if_替换(画布、值、c1、c2、c3、c4):
如果值小于c1:
ac.setBackgroundColor(画布,0,0,0)
返回
elif值
但我感兴趣的是,是否有一种简洁的、类似于python的方法来实现这一点
编辑:有很多很好的答案,但遗憾的是,我只能将其中一个标记为已接受(尽管所有有效的解决方案都经过了投票)。我接受了我在代码中实现的答案,但是对于任何偶然发现这个问题的人来说,一定要看看其他的解决方案,它们都非常优秀。感谢所有写下答案的人。这里有一个可能的解决方案
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)
如果“setBackgroundOpacity”被错误地省略,或者它是否也包含在第一个案例中并不重要,那么您可能正在寻找以下解决方案:
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
color_map=[(3000,0,0,0),
(3700, .2, .4, .2),
(4100, 0, 1, 0),
(4500, 0, 0, 1),
(10**10, 1, 0, 0) ]
对于枚举(颜色映射)中的i,(c,r,g,b):
如果值0:
ac.setBackgroundOpacity(车轮[‘打滑’],1)
打破
编辑:查看了有关setBackgroundOpacity函数的注释
Edit2:修复了打字错误,并为10**10添加了替代解决方案
color_map = [ (3000, 0, 0, 0),
(3700, .2, .4, .2),
(4100, 0, 1, 0),
(4500, 0, 0, 1),
(float("inf"), 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
color_map=[(3000,0,0,0),
(3700, .2, .4, .2),
(4100, 0, 1, 0),
(4500, 0, 0, 1),
(浮动(“inf”),1,0,0)]
对于枚举(颜色映射)中的i,(c,r,g,b):
如果值0:
ac.setBackgroundOpacity(车轮[‘打滑’],1)
打破
c=[[0,0,0],[0,0,0],[2,4,2],[0,1,0],[0,0,1]]
阈值=[3000370041004500]
如果滑动[i]>=4500:
ac.setBackgroundColor(车轮['slip'],1,0,0)
其他:
对于范围(4)内的x:
如果滑动[i]<阈值[x]:
ac.setBackgroundColor(车轮['slip',c[x][0],c[x][1],c[x][2])
打破
如果滑动[i]>=3000:
ac.setBackgroundOpacity(车轮[‘打滑’],1)
这是一种选择,但我个人更喜欢@mpurg的答案。我对它的看法(未测试实际的ac..
调用):
它将映射更新为:
[(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)]
def问题1_5(年龄):
“按年龄打印”
如果在第一种情况下,你是否故意省略了ac.setBackgroundOpacity(wheel['slip',1)
?@trevormerifield,他们似乎在“硬编码”中对其进行了特殊包装例如…所以我猜这不仅仅是一条遗漏的线…但我们永远不知道…@Trevormerifield是的,这是经过深思熟虑的我会使用部分函数来减少重复,但除此之外,我认为您现有的结构是最清晰的(即,目前最可维护的)。这可能会产生意外的副作用。一旦找到匹配项,就应该打破循环。是的,我一发布就注意到了这一点。现在修复了,谢谢你一个小错误:setBackgroundCOlor
应该是setBackgroundCOlor
。这个解决方案直观且易于遵循,我认为在控制流方面非常python,但是10**10
让我有点不舒服。事实上,这并不是最大数量的最佳选择。这是一个整洁、专业的解决方案,但不幸的是,我不能使用functools
,因为这是在精简版Python中运行的-具体来说,它是作为Assetto中的应用程序运行的Corsa.我甚至不能在这里使用dict.items()
。@DavidTan yowsers-我当然不羡慕你:)我花了很长时间才明白这一点,我想问return I+1
有什么作用,但我终于想出来,省去了自己的尴尬:如果value
不在任何范围内,那么它必须是最后一种颜色,因此此行添加一种颜色来选择它。这避免了询问值是否在最后一个界限和无穷大之间的“无穷大攻击”。在我看来,这是一个相当聪明的解决办法。这是我最后使用的,谢谢!很高兴它对你有用!我还只是在答案中添加了另一种思考方式。
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)
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))
[(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)]
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='')