基于真/假值的优雅Python赋值
我有一个变量想根据三个布尔值来设置。最简单的方法就是用一个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风格的方法来处理这个问题。脑海中浮现了几个想法。
字典技巧:
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而互相覆盖的情况。
与/或魔法
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)]