python 条件语句 布尔_关于算法:如何为所有2 ^ N个布尔条件编写If语句(python)

我有一个功能,需要根据输入的查询实例执行查询。

但是随着情况的增加,我列出所有这些都变得很乏味。

例如:

假设我最初有两个条件:

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个语句)..我担心这个数字将来可能会增加。

这是检查这些状况的更好方法吗?

相关:stackoverflow.com/questions/4726949/

如果您想在所有这些情况下都做其他事情,那么现在可以为每种情况写一个语句了,对吗?

== True和== False几乎总是一个(样式)错误。 使用cond_1 and not cond_2)等。

@SvenMarnach:实际上,在循环内部执行的内容略有不同..因为它通常是一个查询..因此,如果条件为true ..则在查询中包含条件值,否则将其从查询中排除。 (SQL查询。从*中选择*如果cond = this和cond_2 = that ..则基本结构是很常见的。但是基于循环,会附加这些条件

您应该举一个例子,说明在个别情况下您正在做什么-这样做可能会更容易。

pythonic不应该用作best的同义词。 pythonic是最受Python开发人员认可的方法。 最好是完全主观的。

您是否需要始终编写所有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

还考虑写作:

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)]()

如果您想在不同条件下采取类似的操作来优化选项数量,请看一下卡诺地图(它比看起来容易):

http://en.wikipedia.org/wiki/Karnaugh_map

关于K-map的NICE技巧,甚至从未想过它们(自从我看过这是很长的时间)。

卡诺地图=第一年CS噩梦

实际上,我喜欢这些地图...非常简单有趣,可以简化复杂的布尔表达式。

永远不要使用== True或== 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的明确提及也更加安全。说if x == True正在测试x的值是否等于名为True的对象引用的值(可以重新定义,尽管这样做非常糟糕)。说if x:表示正在测试在布尔上下文中评估的x是否等于布尔值True(这正是预期的值)。

您正在寻找一种写出真值表的紧凑方式。 (您唯一的另一种选择是找到一种使用布尔代数来简化表达式的方法;简化的形式可能不存在。)除了节省键入内容之外,没有其他方法可以使其更简单:

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): ,

(0,0,1): ,

(0,1,0): ,

(0,1,1): ,

...

}

您也可以使用二进制符号(例如0b110 == 6)按如下方式进行操作,但我发现它不太干净:

{

0b000: ,

0b001: ,

...

}

您甚至可以只使用一个列表,然后将其转换为字典以快速查找(通过执行dict((intToBinarytuple(i),expr) for i,expr enumerate(myList))):

[

# ABC

, # 000

, # 001

, # 010

, # 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):

...

有趣的:)很好的逻辑

如果您的目标是避免编写很多"与"和布尔表达式,则可以使用质数,并且只能使用一个这样的条件(例如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

此hack可使用3个素数用于3个条件,依此类推

您是对的,我错了,我的坏处:(猜猜这意味着我今晚应该停止主持会议。很抱歉,已恢复了所有问题,并删除了(现在)误导性评论。

对不起,我的意思是您可以毫不费力地将素数推广到任意数量的条件,对不起,如果有的话,让我知道您的决定以及我是否错了。

不,我错了,我将乘法与加法混淆了,我在考虑二进制值示例的思路。您的几乎相同,但也有所不同,因此具有优点。忘了我曾经把我的鼻子伸进你的两个答案中:)

我将使用字典将条件以更清晰的方式映射到操作。如果您确实需要针对每种情况做一些不同的事情,那么可能没有比列举各种可能性更好的方法了。

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的倍数之和,然后获取n个大小的条件列表,并将其转换为单个值以进行比较。

>>> 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,...,分别乘以真值(如果是True,则为1,如果是False,则为0)。

这也使您可以查看条件的子集是否为真。如果您需要至少知道一部分条件为真,则可以使用二进制&来找出:

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

如果您使用的是这样的内容,则可能需要对此进行彻底评论。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值