There are a few ways you could do this.
Here's a more robust version of @BingsF's clever answer (this one won't mask exceptions raised within the selected function):
class LoopBreak(Exception):
pass
def zero():
print("Yo")
def one():
print("Hey")
def two():
raise LoopBreak
options = {
0: zero,
1: one,
2: two
}
while True:
try:
response = int(input("Number: "))
action = options[response]
except (ValueError, KeyError):
print("Not a valid response")
continue
try:
action()
except LoopBreak:
break
Or you could specify a special flag in your dictionary that will force a break:
def zero():
print("Yo")
def one():
print("Hey")
options = {
0: zero,
1: one,
2: False
}
while True:
try:
response = int(input("Number: "))
action = options[response]
except (ValueError, KeyError):
print("Not a valid response")
continue
if action is False:
break
else:
action()
Or use a special return value to force a break:
def zero():
print("Yo")
# returns None by default
def one():
print("Hey")
# returns None by default
def two():
return False
options = {
0: zero,
1: one,
2: two
}
while True:
try:
response = int(input("Number: "))
action = options[response]
except (ValueError, KeyError):
print("Not a valid response")
continue
if action() is False:
break
The following code might be more "Pythonic". It could be infinitesimally slower than the approaches above, because it has to check all the if
statements instead of looking up the function in a dictionary via a hash. But it may be easier to read and maintain.
while True:
try:
response = int(input("Number: "))
except ValueError:
response = -1 # error flag
if response == 0:
print("Yo")
elif response == 1:
print("Hey")
elif response == 2:
break
else:
print("Not a valid response")