簡體   English   中英

Python簡化了對多個布爾條件的檢查

[英]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只是整數01的事實,為您提供了以下內容:

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_stuffinputToOutcome以使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM