I have a variable I want to set depending on the values in three booleans. The most straight-forward way is an if statement followed by a series of elifs:
if a a
How about using a dict?
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.
Maybe not much better, but how about
results = ['first', 'second', 'third', 'fourth',
'fifth', 'sixth', 'seventh', 'eighth']
name = results[((not a) << 2) + ((not b) << 1) + (not c)]
I'd go for the list/bits solution of @OscarRyz, @Clint and @Sven, but here's another one:
S1 = frozenset(['first', 'second', 'third', 'fourth'])
S2 = frozenset(['first', 'second', 'fifth', 'sixth'])
S3 = frozenset(['first', 'third', 'fifth', 'seventh'])
last = 'eighth'
empty = frozenset([])
def value(a, b, c):
for r in (a and S1 or empty) & (b and S2 or empty) & (c and S3 or empty):
return r
return last
What about nested ifs - it means you don't have to check everything several times and reads clearer to me (although maybe not quite as clever as some of the other answers):
if a:
if b:
if c:
name="first"
else:
name="second"
else:
if c:
name="third"
else:
name="fourth"
else:
if b:
if c:
name="fifth"
else:
name="sixth"
else:
if c:
name="seventh"
else:
name="eighth"
if a,b,c are really booleans:
li = ['eighth', 'seventh', 'sixth', 'fifth', 'fourth', 'third', 'second', 'first']
name = li[a*4 + b*2 + c]
if they are not booleans:
li = ['eighth', 'seventh', 'sixth', 'fifth', 'fourth', 'third', 'second', 'first']
a,b,c = map(bool,(a,b,c))
name = li[a*4 + b*2 + c]
idea from Clint Miller