基于真/假值的优雅Python赋值

28 投票
11 回答
6650 浏览
提问于 2025-04-16 10:11

我有一个变量想根据三个布尔值来设置。最简单的方法就是用一个if语句,然后跟着一系列的elif:

if a and b and c:
    name = 'first'
elif a and b and not c:
    name = 'second'
elif a and not b and c:
    name = 'third'
elif a and not b and not c:
    name = 'fourth'
elif not a and b and c:
    name = 'fifth'
elif not a and b and not c:
    name = 'sixth'
elif not a and not b and c:
    name = 'seventh'
elif not a and not b and not c:
    name = 'eighth'

这样写有点别扭,我在想有没有更符合Python风格的方法来处理这个问题。脑海中浮现了几个想法。

  1. 字典技巧:

    name = {a and b and c: 'first',
            a and b and not c: 'second',
            a and not b and c: 'third',
            a and not b and not c: 'fourth',
            not a and b and c: 'fifth',
            not a and b and not c: 'sixth',
            not a and not b and c: 'seventh',
            not a and not b and not c: 'eighth'}[True]
    

我称之为技巧,因为我不太喜欢七个键都是False而互相覆盖的情况。

  1. 与/或魔法

    name = (a and b and c and 'first' or
            a and b and not c and 'second' or
            a and not b and c and 'third' or
            a and not b and not c and 'fourth' or
            not a and b and c and 'fifth' or
            not a and b and not c and 'sixth' or
            not a and not b and c and 'seventh' or
            not a and not b and not c and 'eighth')
    

这个方法有效是因为Python中的与和或会返回最后一个被评估的值,但你得知道这一点才能理解这段看起来有点奇怪的代码。

这三种选择都不是特别令人满意。你有什么推荐的办法吗?

11 个回答

11

可能没什么太大的改进,但这样怎么样呢

results = ['first', 'second', 'third', 'fourth', 
           'fifth', 'sixth', 'seventh', 'eighth']
name = results[((not a) << 2) + ((not b) << 1) + (not c)]
30

用字典怎么样?

name = {(True, True, True): "first", (True, True, False): "second",
        (True, False, True): "third", (True, False, False): "fourth",
        (False, True, True): "fifth", (False, True, False): "sixth",
        (False, False, True): "seventh", (False, False, False): "eighth"}

print name[a,b,c] # prints "fifth" if a==False, b==True, c==True etc.
50

你可以把a、b和c看作是三个二进制位,当它们组合在一起时,可以形成一个0到7之间的数字。然后,你可以有一个包含值['first', 'second', ... 'eighth']的数组,利用这个数字作为数组的索引来获取对应的值。这其实只需要两行代码(第一行是把这三个二进制位组合成一个0到7之间的值,第二行是用这个值去查找数组中的内容)。

下面是代码:

nth = ['eighth', 'seventh', 'sixth', 'fifth', 'fourth', 'third', 'second', 'first']
nth[(a and 4 or 0) | (b and 2 or 0) | (c and 1 or 0)]

撰写回答