正确退出While循环错误

时间:2011-08-23 15:26:42

标签: python while-loop

我很好奇用while循环处理这个错误的'正确'pythonic方法是什么。在这个例子中,我可以简单地检查字符串以查看它是否具有[-1]字符,但是我的问题所基于的实例​​代码要复杂得多。

try:
    while mystring[-1] == '!' #Will throw an error if mystring is a blank string
         print("Exclamation!")
         mystring = mystring[:-1]
    return mystring
except:
    return ""

实际上我的问题是我的while循环取决于检查,有时在循环中的一些处理之后,将抛出错误。以上只是该问题的简化(可能过于简化)。我用一系列的尝试修正了它:除了:但是我觉得这不是解决这个问题的“正确”方法。

3 个答案:

答案 0 :(得分:3)

对于您的示例,您可以执行以下操作:

while mystring and mystring[-1] == '!':
    print("Exclamation!")
    mystring = mystring[:-1]
return mystring

这将有效,因为如果mystring为空,它会短路并结束循环,所以你永远不会尝试访问空字符串的-1索引

编辑:正如温斯顿指出的那样,你可以使用str.endswith来摆脱所有特殊的外壳,如下面的代码所示

while mystring.endswith('!'):
    print("Exclamation!")
    mystring = mystring[:-1]
return mystring

答案 1 :(得分:3)

您当前代码执行的两件事情,您不应该这样做:

  1. 捕获任何异常,您应该只捕获特定的兴趣异常
  2. 在try块中包含整个循环,如果可能的话,只应该包含引发异常的语句/表达式
  3. 如果你发现自己在python中使用了很多while循环,那么它表明你没有最有效地使用python。给定python的工具集,你几乎应该总是使用某种for循环。如果没有看到代码的真实样本,我不能说这是否真的如此。如果您需要该领域的帮助,请在http://codereview.stackexchange.com

    发布一些代码

    这个问题的一般解决方案是编写一个处理异常的函数并使用它。

    def last_character(string):
        try:
           return string[-1]
        except IndexError:
           return ' '
    
    while last_character(mystring) == '!'
        mystring = mystring[:-1]
    return mystring
    

    事实上,在许多情况下,标准结构已经没有异常等价物。可以使用.endswith()方法轻松编写此循环。通过使用或自己制作,您可以最干净地处理异常。

答案 2 :(得分:2)

使用mystring.rstrip('!')删除字符串末尾的'!'字符; - )

如果问题复杂得多,正确的方法是捕获操作抛出的IndexError。

try:
    while mystring[-1] == '!' #Will through an error if mystring is a blank string
         print("Exclamation!")
         mystring = mystring[:-1]
    return mystring
except IndexError:
    return ""

另一种方法是检查字符串是否为空,并避免使用引发异常的操作:

while mystring and mystring[-1] == '!': # lazy boolean expression evaluation
      mystring = mystring[:-1]
return mystring

没有延迟布尔表达式评估的其他版本:

if not mystring:
    return mystring
while mystring[-1] == '!':
    mystring = mystring[:-1]
    if not mystring:
        break
return mystring

我个人赞成第二个版本,特别是如果你更改mystring [-1] =='!'使用mystring.endswith('!')(但在这种情况下,您不需要检查空白,因为结束已经为您执行此操作)。