如何写所有2^N布尔条件(python)的if语句
我有一个函数,需要根据输入的查询实例执行查询.. 但随着条件的增加,对我来说变得单调乏味列出他们全部。 例如: 假设我有两个条件最初:如何写所有2^N布尔条件(python)的if语句
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
....
所以我想,如果条件发生在二进制值然后有2^N语句我必须写:(
所以现在我有3个条件变量(8个报表)..我恐怕这个数字可能在将来增加。 是tehre更好的方法来检查这些条件?
待办事项ÿ你需要总是写出所有2^n种可能性吗?
而且是所有的东西,你必须做不同的(因此也是2^n项操作?)
不过我可以给一些提示:
不要使用“== true”或“==假”
你写什么等于:
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
想想也写:
if cond_1:
if cond_2:
Do something
else:
Do something
else:
if cond_2:
Do something
else:
Do something
您还可以根据值定义功能:
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
....
,并称之为:
self.actions[(cond_1, cond_2)]()
如果你想优化的情况下,期权的数量,您有类似的不同条件行动,看看卡诺图(看起来比它容易):
KICE地图上的NICE提示,从来没有想到过它们(这是我看过它们以来的一个长时间) – 2012-03-01 23:30:25
卡诺拉地图= 1年CS恶梦 – UmNyobe 2012-03-07 15:52:56
实际我喜欢这些地图......非常简单而有趣,可以简化复杂的布尔表达式。 – 2012-03-07 16:51:28
您应该never test a boolean variable with == True
or == False
。相反,只需使用布尔值就足够了。如果你想掩盖真值的几乎每一个组合,你可能还需要嵌套,就像这样:
if cond_1:
if cond_2:
do something
else:
do something else
elif cond_2:
do this
如果数量比进一步增加,我建议的地图,像这样:
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()
但是,请注意,大量不同的情况是肯定的代码异味。几乎在任何情况下,实际上并不需要这么多的情况,并且实际上可以直接调用一个函数。你可能认为你的情况是个例外,但事实并非如此。你为什么需要这么多案件?
“你不应该用== True或== False测试一个布尔变量” - 除了可读性/样式考虑之外,省略显式提及True和False的比较也更安全。如果x的值等于名为'True'的对象引用的值(可以重新定义,尽管非常糟糕的做法),那么说'if x == True'就是测试。如果x在布尔上下文中评估,则评估为布尔值True(这正好是*所预期的)。 – 2012-03-01 23:41:45
我会使用一个词典以更清晰的方式将条件映射到动作。如果你真的需要为每种情况做不同的事情,那么可能没有比列举可能性更好的方法。
def do_something():
pass
def do_something_else():
pass
def do_this():
pass
do_dict = {(True, False): do_something,
(True, True): do_something_else,
(False, True): do_this}
# call it
do_dict[(cond_1, cond_2)]()
如果你的目标是避免编写大量“阿富汗国家发展战略”和布尔表达式,你可以使用质数,只有一个条件,像这样(例如2个条件)
cond = (2**cond_1)*(3**cond_2)
所以
cond == 1 #means cond_1 and cond_2 are False
cond == 2 #means cond_1 is True and con_2 is False
cond == 3 #means cond_1 is False and con_2 is True
cond == 6 #means con_1 and Con_2 are True
这个技巧可用于3种条件下使用3张素等
你是对的,我错了,我的坏:(猜猜这意味着我应该停止对今晚的主持。对不起,这两个问题恢复和(现在)误导评论删除。 – 2012-03-02 00:13:50
对不起,我的观点是,你可以概括如果有任何问题,请填写任意数量的条件,对不起,如果有任何问题,请让我知道您的决定以及我是否有错误 – ChessMaster 2012-03-02 00:14:38
不,我错了,我将乘法与加法混淆了,我正在考虑沿着二进制值的例子。你的是几乎相同的,但也不同,所以它的优点。忘记我曾经开过我的鼻子到你的两个答案:) – 2012-03-02 00:15:47
可以采取N大小的条件列表中,并把它转换成一个单一的值进行比较,通过将条件成2.
>>> conditions = [True, False, True, True, False]
>>> condition = sum(2**i * cond for i, cond in enumerate(conditions))
>>> condition
13
倍数的条件的第一个值是2^0 = 1
的总和,第二是2^1 = 2
,第三被2^2 = 4
, ...分别乘以真值(1如果True
,0如果False
)。
这还允许您查看条件的子集是否为真。如果您需要了解的情况,至少一个子集是真实的,你可以使用二进制&
找出:
>>> subset = lambda c, x: (c & x) == x
>>> conditions = [True, False, True, True, False, True, True, True, True]
>>> condition = sum(2**i * cond for i, cond in enumerate(conditions))
>>> subset(condition, 13)
True
>>> subset(condition, 2)
False
具有由以前的一些答案的提供的功能,而不是使用字典,你也可以使用列表和字典来将条件映射到行为。您也可以实现defaultdict
样的功能与列表(虽然使用2^n个存储器,而且很可能不是最好的主意):
def do_something():
print("Hello World!")
condition_action_map = [None] * (2 ** len(conditions))
condition_action_map[13] = do_something
你可能会想如果你使用的东西彻底评论此喜欢这个。
您正在寻找一种简洁的方式来写出真值表。 (你的唯一选择就是找到一种方法,使用布尔代数来简化你的表情;用简单的形式可能不存在。)有没有办法让这个简单,除了以节省打字:
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]
演示:
myFunc = TruthTable('''
000 1
001 0
010 0
011 1
100 1
101 0
110 0
111 1
''')
输出:
>>> myFunc(False, False, True)
False
如果你需要比布尔输出的更多,你可以适应ŧ他通过使用例如字典指任意表达式,和后处理的按键为布尔值的元组:
{
(0,0,0): <expr0>,
(0,0,1): <expr1>,
(0,1,0): <expr2>,
(0,1,1): <expr3>,
...
}
你也可以做它用二进制表示如下(如0b110 == 6
),但我觉得它更干净:
{
0b000: <expr0>,
0b001: <expr1>,
...
}
你甚至可以只使用它你以后转换成字典快速查找(做dict((intToBinarytuple(i),expr) for i,expr enumerate(myList))
)的列表:
[
# ABC
<expr0>, # 000
<expr1>, # 001
<expr2>, # 010
<expr3>, # 011
...
]
旁注:万一你需要任意的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):
...
有趣的:)很不错的逻辑 – Fraz 2012-03-02 01:33:00
相关:http://stackoverflow.com/questions/4726949/python-elegant-assignment-based-on-true-false-values – 2012-03-01 23:05:24
如果你想在所有这些情况下做其他事情,那么现在有方式为每个案例写一份声明,对吗? – 2012-03-01 23:06:15
'== True'和'== False'几乎总是一个(文体)错误。使用'cond_1而不是cond_2)'等 – 2012-03-01 23:07:47