Python – 使用 `while`、`try`、`if` 和 `except` 语句跳出深层嵌套循环
Python – Breaking out of a deeply nested loop with `while`, `try`, `if`, and `except` statements
这是我的代码,它根据用户输入 a, b, c
求解二次方程。但是,我想检查不正确的用户输入。如果用户输入除浮点数以外的任何内容,用户将面临 print "Not a valid input. Try again.\n"
,然后是函数循环 quadratic2()
。然而,这个程序是一个更大程序的一部分,所以我希望用户可以选择输入 "next"
来终止这个函数并继续。我的问题是我要求 3 个用户输入,但我希望 "next"
输入是第一个输入,a
。在用户输入随机字符串之前,这种方法运行良好,导致 ValueError
。一旦发生这种情况,我的代码不想循环回去检查输入是否为 next
。请帮我!我觉得这段代码的嵌套方式让我很困惑。
def retest3():
print "Type in another a, b, and c. Or type \"Next\" to move on."
def quadratic1():
print ("This program calculates the zeroes of a quadratic equation."
"\nPlease enter a, b, and c, hitting \"Enter\" after each one: ")
def quadratic2():
while 1 == 1:
a = (raw_input())
if "next" == a.lower():
ontonextthing()
return 1 == 0
else:
try:
a = float(a)
except ValueError:
print "Not a valid input. Try again.\n"
quadratic2()
try:
b = float(raw_input())
except ValueError:
print "Not a valid input. Try again.\n"
quadratic2()
try:
c = float(raw_input())
except ValueError:
print "Not a valid input. Try again.\n"
quadratic2()
if b**2-4*a*c>0:
root1=(-b+math.sqrt(b**2-4*a*c))/(2*a)
root2=(-b-math.sqrt(b**2-4*a*c))/(2*a)
print ("First Root: {0}\nSecond Root: {1}".format(root1,root2))
else:
print ("The discriminant is negative, so your"
" roots will contain \"i\".")
disc1=(b**2-4*a*c)
disc2=-disc1
sqrtdisc2=(math.sqrt(disc2))/(2*a)
b2=(-b)/(2*a)
print ("{0} + {1}i".format(b2, sqrtdisc2))
print ("{0} - {1}i\n".format(b2, sqrtdisc2))
retest3()
quadratic1()
quadratic2()
This works perfectly well until the user types in a random string, causing a ValueError. Once this happens, my code does not want to loop back to check for if the input is next.
您似乎想要 continue
statement:
try:
b = float(raw_input())
except ValueError:
print "Not a valid input. Try again.\n"
continue
continue
语句将您带回到 while
循环(下一次迭代)的开头。目前你正在调用 quadratic2()
这使得你的函数递归,而不是你想要的。
因为它是递归的,所以当您收到异常时它会退出当前函数,但是因为您使用的是递归,所以您只需 return 回到您在 (这是相同的功能)。因此,您输入的下一个输入可能会被
解析
b = float(raw_input())
而不是
a = (raw_input())
您的问题的 "real" 解决方案首先是 不要使用深度嵌套的结构 。深度嵌套的语句使您的代码难以阅读、难以测试、难以维护和难以重用。此外,您将倾向于重复代码,这很糟糕。尤其是在Python中,深度嵌套会让你计算空格来正确缩进,这真是令人头疼。
将您的代码分解为函数,并遵循 "single responsibility principle" 让一个函数只做一件事。这有几个优点:
- 你不必把太多的东西放在脑子里。专注于一个小问题,把它搞定。
- 您总是可以
return
在函数的早期,这样您就可以在许多情况下避免嵌套。
- 您可以在函数中重用代码。
- 你没有重复的代码:如果你想改变一个特定的行为,改变一个函数而不是一个函数中的几个地方。
- 您可以单独测试您的功能,确保它们做正确的事情。
在你的例子中,quadratic2
函数做了很多事情:
- 运行是一个"main loop"
- 它读取用户输入的命令
- 它调度命令
- 它读取用户输入的值
- 它处理无效的用户输入
- 它进行计算
- 将结果显示给用户
现在我不是说你需要一个函数来处理上面列出的每个细节,但很明显这个函数做的太多了。
关于如何分解它的示例:
- 为主循环和调度命令创建一个函数。让命令(例如"next")在单独的函数中处理。
- 写一个函数从用户那里读入一个
float
,并调用这个函数三次而不是重复try...except
代码三次。这有一个额外的好处,你可以在一个循环中将这个功能增强到 运行,这样用户就可以重复输入一个值,而不是像你当前的解决方案那样必须重新开始。
其他提示:
- 不要在
return
、raise
、break
或 continue
后使用 else
。没必要,因为无论如何都不会到达下一条语句,您可以节省一个嵌套级别。
- 不要使用像
1==1
或 1==0
这样容易混淆的表达方式。这只是True
和False
的复杂写法。在您的示例中,它应该改为 while True
和 return False
。
这是我的代码,它根据用户输入 a, b, c
求解二次方程。但是,我想检查不正确的用户输入。如果用户输入除浮点数以外的任何内容,用户将面临 print "Not a valid input. Try again.\n"
,然后是函数循环 quadratic2()
。然而,这个程序是一个更大程序的一部分,所以我希望用户可以选择输入 "next"
来终止这个函数并继续。我的问题是我要求 3 个用户输入,但我希望 "next"
输入是第一个输入,a
。在用户输入随机字符串之前,这种方法运行良好,导致 ValueError
。一旦发生这种情况,我的代码不想循环回去检查输入是否为 next
。请帮我!我觉得这段代码的嵌套方式让我很困惑。
def retest3():
print "Type in another a, b, and c. Or type \"Next\" to move on."
def quadratic1():
print ("This program calculates the zeroes of a quadratic equation."
"\nPlease enter a, b, and c, hitting \"Enter\" after each one: ")
def quadratic2():
while 1 == 1:
a = (raw_input())
if "next" == a.lower():
ontonextthing()
return 1 == 0
else:
try:
a = float(a)
except ValueError:
print "Not a valid input. Try again.\n"
quadratic2()
try:
b = float(raw_input())
except ValueError:
print "Not a valid input. Try again.\n"
quadratic2()
try:
c = float(raw_input())
except ValueError:
print "Not a valid input. Try again.\n"
quadratic2()
if b**2-4*a*c>0:
root1=(-b+math.sqrt(b**2-4*a*c))/(2*a)
root2=(-b-math.sqrt(b**2-4*a*c))/(2*a)
print ("First Root: {0}\nSecond Root: {1}".format(root1,root2))
else:
print ("The discriminant is negative, so your"
" roots will contain \"i\".")
disc1=(b**2-4*a*c)
disc2=-disc1
sqrtdisc2=(math.sqrt(disc2))/(2*a)
b2=(-b)/(2*a)
print ("{0} + {1}i".format(b2, sqrtdisc2))
print ("{0} - {1}i\n".format(b2, sqrtdisc2))
retest3()
quadratic1()
quadratic2()
This works perfectly well until the user types in a random string, causing a ValueError. Once this happens, my code does not want to loop back to check for if the input is next.
您似乎想要 continue
statement:
try:
b = float(raw_input())
except ValueError:
print "Not a valid input. Try again.\n"
continue
continue
语句将您带回到 while
循环(下一次迭代)的开头。目前你正在调用 quadratic2()
这使得你的函数递归,而不是你想要的。
因为它是递归的,所以当您收到异常时它会退出当前函数,但是因为您使用的是递归,所以您只需 return 回到您在 (这是相同的功能)。因此,您输入的下一个输入可能会被
解析b = float(raw_input())
而不是
a = (raw_input())
您的问题的 "real" 解决方案首先是 不要使用深度嵌套的结构 。深度嵌套的语句使您的代码难以阅读、难以测试、难以维护和难以重用。此外,您将倾向于重复代码,这很糟糕。尤其是在Python中,深度嵌套会让你计算空格来正确缩进,这真是令人头疼。
将您的代码分解为函数,并遵循 "single responsibility principle" 让一个函数只做一件事。这有几个优点:
- 你不必把太多的东西放在脑子里。专注于一个小问题,把它搞定。
- 您总是可以
return
在函数的早期,这样您就可以在许多情况下避免嵌套。 - 您可以在函数中重用代码。
- 你没有重复的代码:如果你想改变一个特定的行为,改变一个函数而不是一个函数中的几个地方。
- 您可以单独测试您的功能,确保它们做正确的事情。
在你的例子中,quadratic2
函数做了很多事情:
- 运行是一个"main loop"
- 它读取用户输入的命令
- 它调度命令
- 它读取用户输入的值
- 它处理无效的用户输入
- 它进行计算
- 将结果显示给用户
现在我不是说你需要一个函数来处理上面列出的每个细节,但很明显这个函数做的太多了。
关于如何分解它的示例:
- 为主循环和调度命令创建一个函数。让命令(例如"next")在单独的函数中处理。
- 写一个函数从用户那里读入一个
float
,并调用这个函数三次而不是重复try...except
代码三次。这有一个额外的好处,你可以在一个循环中将这个功能增强到 运行,这样用户就可以重复输入一个值,而不是像你当前的解决方案那样必须重新开始。
其他提示:
- 不要在
return
、raise
、break
或continue
后使用else
。没必要,因为无论如何都不会到达下一条语句,您可以节省一个嵌套级别。 - 不要使用像
1==1
或1==0
这样容易混淆的表达方式。这只是True
和False
的复杂写法。在您的示例中,它应该改为while True
和return False
。