[英]Python simplify checking multiple boolean conditions
我有一個函數,可以檢查3個不同的布爾標志,並且對於8個組合的每一個都有唯一的結果。
"""
a | b | c | out
- + - + - + ---
0 | 0 | 0 | 0
0 | 0 | 1 | 1
0 | 1 | 0 | 2
0 | 1 | 1 | 3
1 | 0 | 0 | 4
1 | 0 | 1 | 5
1 | 1 | 0 | 6
1 | 1 | 1 | 7
"""
def do_stuff(a, b, c):
if a:
if b:
if c:
return function7() # a, b, c
return function6() # a, b, !c
if c:
return function5() # a, !b, c
return function4() # a, !b, !c
else:
if b:
if c:
return function3() # !a, b, c
return function2() # !a, b, !c
if c:
return function1() # !a, !b, c
return function0() # !a, !b, !c
自返回(退出循環)以來,我已經捷徑了很多else
語句。
還有更干的方法來完成此操作嗎? 我可以轉換為二進制,並執行if / elif的單個深度級別,但是我不想使用“幻數”。
此外,我意識到這僅是16行代碼的8個結果,但是如果它是4個變量,有什么辦法可以提高可讀性/流程?
您需要某種從結果到功能的映射以及從輸入到結果的映射。 您在頂部提供的漂亮表,加上Python中的bool
只是整數0
和1
的事實,為您提供了以下內容:
outcomeToFunc {
0: function0,
1: function1,
2: function2,
3: function3,
4: function4
# etc...
}
def inputToOutcome(a, b, c):
return a << 2 | b << 1 | c
def do_stuff(a, b, c):
outcome = inputToOutcome(a, b, c)
return outcomeToFunc[outcome]()
如果您對具有任意數量的布爾輸入感興趣,則可以修改do_stuff
和inputToOutcome
以使用varargs:
outcomeToFunc {
0: function0,
1: function1,
2: function2,
3: function3,
4: function4
# etc...
}
def inputToOutcome(*args):
outcome = 0
n = len(args) - 1
for ind, arg in enumerate(args):
outcome |= bool(arg) << (n - ind)
return outcome
def do_stuff(*args):
outcome = inputToOutcome(*args)
try:
return outcomeToFunc[outcome]()
except KeyError:
raise ValueError('Outcome {} not supported'.format(outcome))
這是兩個解決方案。 您可以自行決定它們是否比您提出的更漂亮。
def do_stuff(a, b, c):
flags = bool(a), bool(b), bool(c)
if flags == (True, True, True):
return function7()
if flags == (True, True, False):
return function6()
if flags == (True, False, True):
return function5()
if flags == (True, False, False):
return function4()
if flags == (False, True, True):
return function3()
if flags == (False, True, False):
return function2()
if flags == (False, False, True):
return function1()
if flags == (False, False, False):
return function0()
def do_stuff(a, b, c):
control = {
(True, True, True): function7,
(True, True, False): function6,
(True, False, True): function5,
(True, False, False): function4,
(False, True, True): function3,
(False, True, False): function2,
(False, False, True): function1,
(False, False, False): function0,
}
return control[bool(a), bool(b), bool(c)]()
首先,您可以構建一個二進制到十進制的轉換器。獲取新的數字后,您可以通過eval函數按字符串中的函數名稱來調用方法:
def function0():
print("function0")
def function1():
return 1;
a = eval("function1()")
print(a)
請記住,除非使用當前的全局名稱ID,否則您可以將全局變量傳遞給eval函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.