if,elif,else链不能正常工作?

时间:2011-09-18 17:53:09

标签: python

我正在努力学习“以艰难的方式学习Python”,我遇到了障碍。本书给出了单元测试,并要求您编写一个函数来满足测试要求。但是,当我将此函数导入交互式shell以进行测试时,任何输入都会返回“方向”,我无法弄清楚原因。

这是我的代码:

def pos(item):
    """ Get part of speech for item. """
    pos = ''
    if item == 'north' or 'south' or 'east':
        return 'direction'
    elif item == 'go' or 'kill' or 'eat':
        return 'verb'
    elif item == 'the' or 'in' or 'of':
        return 'stop'
    elif item == 'bear' or 'princess':
        return 'noun'
    else:
        try:
            int(item)
            return 'number'
        except ValueError:
            return 'error'

3 个答案:

答案 0 :(得分:8)

你应该写下这个:

if item == 'north' or item == 'south' or item == 'east':

或者,或者:

if item in ('north', 'south', 'east'):

同样适用于其余分支。

要解释原始代码失败的原因,请考虑Python如何解析以下表达式:

item == 'north' or 'south' or 'east'

Python的作用如下(注意表示解析顺序的括号):

(item == 'north') or 'south' or 'east'

这里有三个子表达式。 item == 'north'可能是假的(除非你碰巧输入了'north')。但是,'south''east'在布尔上下文(即条件)中进行评估时始终为True,因此您最终会得到(item == 'north') or True or True,这当然是True {1}}。

答案 1 :(得分:4)

您使用or错误。它应该是

if item == 'north' or item == 'south' or item == 'east':

或更具惯用性

if item in ('north', 'south', 'east')

出现错误的原因是因为Python将括号放在表达式中。你可能认为它正在做

if item == ('north' or 'south' or 'east')

但实际发生的是

if (item == 'north') or ('south') or ('east')

'south'是非空字符串,始终为True。 (虽然前者也不起作用,因为'north' or 'south' or 'east'因为Python短路'east'的方式而被评估为or。但是这更复杂,你不需要担心它。)


顺便说一句,你可能更喜欢以下习语,尽管你的习惯同样好。

items = {}
items['north'] = items['south'] = items['east'] = 'direction'
items['go'] = items['kill'] = items['eat'] = 'verb'
items['the'] = items['in'] = items['of'] = 'stop'
items['bear'] = items['princess'] = 'noun'

try:
    return items[item]
except KeyError:
    pass

try:
    int(item)
except ValueError:
    pass
else:
    return 'number'

return 'error'

答案 2 :(得分:1)

if item == 'north' or 'south' or 'east':

确定或之间的所有事物的真值。非空字符串具有真正的真值,因此在给定输入'west'的情况下,这将评估为:

if False or True or True:

相反,你想要

if item == 'north' or item == 'south' or item == 'east':

,或更多pythonic:

if item in ('north', 'south', 'east'):