我有一个函数需要根据输入的查询实例执行查询..但随着条件的增加,我列出所有这些都变得乏味.例如:假设我最初有两个条件:
if (cond_1 == True and cond_2 == False):
do something
elif cond_1 == True and cond_2 == True:
do something else
elif cond_1 == False and cond_2 == True:
do this
Run Code Online (Sandbox Code Playgroud)
....
所以我猜如果条件采用二进制值,那么我必须写2 ^ n个语句:(
所以现在我有3个条件变量(8个语句)..我担心这个数字将来会增加.这是检查这些条件的更好方法吗?
你是否需要总是写出所有2 ^ n种可能性?
你需要做的所有事情都是不同的(所以2 ^ n动作也是如此?)
不过我可以给出一些提示:
不要使用'== True'或'== False'
你写的等于:
if cond_1 and not cond_2:
do something
elif cond_1 and cond_2:
do something else
elif not cond_1 and cond_2:
do this
Run Code Online (Sandbox Code Playgroud)
还要考虑写作:
if cond_1:
if cond_2:
Do something
else:
Do something
else:
if cond_2:
Do something
else:
Do something
Run Code Online (Sandbox Code Playgroud)
您还可以根据值定义函数:
def __init__(self):
self.actions = {
(False, False): action_1,
(False, True ): action_2,
...
}
def action_1(self):
some action
def action_2(self):
some action
....
Run Code Online (Sandbox Code Playgroud)
并称之为:
self.actions[(cond_1, cond_2)]()
Run Code Online (Sandbox Code Playgroud)
如果您想要在具有类似操作的不同条件的情况下优化选项数量,请查看Karnaugh Maps(它比它看起来更容易):
http://en.wikipedia.org/wiki/Karnaugh_map
你永远不== True== False应该用或测试一个布尔变量.相反,只使用布尔值就足够了.如果你想覆盖几乎所有真值的组合,你可能也想要嵌套,如下所示:
if cond_1:
if cond_2:
do something
else:
do something else
elif cond_2:
do this
Run Code Online (Sandbox Code Playgroud)
如果数字进一步增加,我会建议一张地图,如下所示:
call_map = {
(True, True, True): func1,
(True, False, True): func2,
(True, False, False): func3,
}
try:
func = call_map[(cond_1, cond_2, cond_3)]
except KeyError:
pass
else:
func()
Run Code Online (Sandbox Code Playgroud)
但请注意,大量不同的案例是一种确定的代码味道.实际上,在任何情况下,您实际上并不需要这么多情况,并且实际上可以直接调用函数.您可能认为您的案例是例外,但可能不是.你为什么需要这么多案件?
您正在寻找一种写出真值表的简洁方法.(你唯一的另一种选择是找到一种使用布尔代数简化表达式的方法;可能不存在简化形式.)除了节省输入之外,没有办法使这更简单:
def TruthTable(text):
table = {}
for line in text.splitlines():
line = line.strip()
if line:
inputs,output = line.split()
table[tuple(bool(int(x)) for x in inputs)] = bool(int(output))
return lambda *inputs:table[inputs]
Run Code Online (Sandbox Code Playgroud)
演示:
myFunc = TruthTable('''
000 1
001 0
010 0
011 1
100 1
101 0
110 0
111 1
''')
Run Code Online (Sandbox Code Playgroud)
输出:
>>> myFunc(False, False, True)
False
Run Code Online (Sandbox Code Playgroud)
如果您需要的不仅仅是布尔输出,您可以通过使用例如字典来调整它以引用任意表达式,并将键后处理为布尔元组:
{
(0,0,0): <expr0>,
(0,0,1): <expr1>,
(0,1,0): <expr2>,
(0,1,1): <expr3>,
...
}
Run Code Online (Sandbox Code Playgroud)
您也可以使用二进制表示法(例如0b110 == 6)执行以下操作,但我发现它不那么干净:
{
0b000: <expr0>,
0b001: <expr1>,
...
}
Run Code Online (Sandbox Code Playgroud)
您甚至可以使用一个列表,稍后您将其转换为字典以进行快速查找(通过执行dict((intToBinarytuple(i),expr) for i,expr enumerate(myList))):
[
# ABC
<expr0>, # 000
<expr1>, # 001
<expr2>, # 010
<expr3>, # 011
...
]
Run Code Online (Sandbox Code Playgroud)
旁注:万一你需要任意python命令,你可以像这样调度:
conditions = (True, False, True)
c = lambda *args: conditions==toBooleanTuple(args)
if c(0,0,0):
...
elif c(0,0,1):
...
elif c(0,1,0):
...
elif c(0,1,1):
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1542 次 |
| 最近记录: |