【问题标题】:Python elif Statement acting unconditionalPython elif 语句无条件执行
【发布时间】:2012-09-16 03:09:18
【问题描述】:

不知道为什么我的代码默认使用这个 elif。但它永远不会到达 else 语句。甚至在最后一个 elif 中将索引抛出边界错误。

请忽略我不使用正则表达式。这个家庭作业不允许。问题是 else 语句之前的最后一个 elif。

if item == '':
    print ("%s\n" % item).rstrip('\n')

elif item.startswith('MOVE') and not item.startswith('MOVEI'):
    print 'Found MOVE'

elif item.startswith('MOVEI'):
    print 'Found MOVEI'

elif item.startswith('BGT'):
    print 'Found BGT'

# ...

elif item.find(':') and item[(item.find(':') -1)].isalpha():
    print 'Mya have found a label'

else:
    # Never get to this branch
    print 'Not sure what I found'

【问题讨论】:

  • 在发布 Python 代码时要注意缩进。
  • 好点。我对此表示歉意。
  • 您可以通过单击问题下方的“编辑”链接来修复它。
  • 您正在验证的项目中的测试数据是什么?

标签: python


【解决方案1】:

当在item 中找不到“:”时,item.find(':') 将返回-1

-1 被评估为True-ish,因此这可能是您问题的根源。仅当“:”位于item 的开头时,if item.find(':') 才会匹配。

要解决问题,只需替换这一行:

elif item.find(':') and item[(item.find(':') -1)].isalpha():

用这一行:

elif ':' in item and item[item.find(':') - 1].isalpha():

这将有效地检查“:”前面的字符是否为字母数字。

【讨论】:

  • 嗯好的。那么我将如何重新编写该语句以在字符串中查找 ':' 并检查之前的字符是否为 alpha?
  • @BradCarvalho:查看更新后的答案。您只需更改 find 部分即可与 -1 进行比较。如果find() 的结果等于-1,则表示该字符串尚未找到。否则,它将为您提供职位。请记住,如果find() 返回0: 位于字符串的开头,因此,您将检查最后一个字符(位于-1 位置,所以从末尾开始) ) 是 alpha。
  • @BradCarvalho:没问题,不客气。除了item.find(':') != -1,你还可以使用':' in item,它更短、更清晰、更pythonic。
  • @DavidHarkness:你说得对,: 位于字符串的开头——我在 cmets 中提到了它,Blender 也添加了有关它的信息。但是,除非此代码中有更多内容,否则不会有异常(如果您谈论的是可以引发和捕获的实际 Python 异常)。
  • 与其尝试使用.find 并计算索引,不如考虑使用.partition 将冒号周围的字符串分开。
【解决方案2】:
  • 你的if 案子真奇怪:

    print ("%s\n" % item).rstrip('\n')
    

    如果item == ''(item + '\n').rstrip('\n') 将等于item,即''。我很确定您可以摆脱该代码。

  • 重新排序if 语句可以消除MOVEI/MOVE 问题。
  • 添加到Tadeck's answer,您需要使用item.find(':') > 0 作为您的条件。如果您的字符串以:string[0 - 1] == string[-1] 开头,这是您的字符串的最后一个 字符。

这是一个可能已修复的代码版本

if item == '':
    print ''
elif item.startswith('MOVEI'):
    print 'Found MOVEI'
elif item.startswith('MOVE'):
    print 'Found MOVE'
elif item.startswith('BGT'):
    print 'Found BGT'
elif item.startswith('ADD'):
    print 'Found ADD'
elif item.startswith('INC'):
    print 'Found INC'
elif item.startswith('SUB'):
    print 'Found SUB'
elif item.startswith('DEC'):
    print 'Found DEC'
elif item.startswith('MUL'):
    print 'Found MUL'
elif item.startswith('DIV'):
    print 'Found DIV'
elif item.startswith('BEQ'):
    print 'Found BEQ'
elif item.startswith('BLT'):
    print 'Found BLT'
elif item.startswith('BR'):
    print 'Found BR'
elif item.startswith('END'):
    print 'Found END'
elif item.find(':') > 0 and item[(item.find(':') - 1)].isalpha():
    print 'Mya have found a label'
else:
    print 'Not sure what I found'

这是您的代码稍微更 Pythonic 的版本:

def test_item(item):
  tests = ['MOVEI', 'MOVE', 'BGT', 'ADD', 'INC', 'SUB', 'DEC', 'MUL', 'DIV', 'BEQ', 'BLT', 'BR', 'END']

  for test in tests:
    if item.startswith(test):
      return 'Found ' + test

  if item.find(':') > 0 and item[(item.find(':') - 1)].isalpha():
    return 'Mya have found a label'
  else:
    return 'Not sure what I found'

【讨论】:

  • 这也是有道理的。谢谢!
  • +1 没错。如果仅此而已,我们还可以缩短代码(通过将所有这些“startswith”条件转换为一个)。但我相信我们看不到的(其他代码)包含更多问题,所以我只针对 OP 报告的问题给出了解决方案。无论如何,很好的答案。
  • 我喜欢你在那里所做的。但是,那些打印“找到”语句只是我需要根据匹配开始进行的额外检查的占位符。它们中的每一个也是不同的检查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-03
  • 2017-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多