if、elif、else链不正确?
我正在学习《Learn Python the Hard Way》这本书,但遇到了一些困难。书里给了一个单元测试,让你写一个函数来满足这些测试。但是当我把这个函数导入到交互式命令行中测试时,无论输入什么,都会返回'direction',我搞不清楚为什么。
这是我的代码:
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 个回答
1
if item == 'north' or 'south' or 'east':
这个部分用来判断在“或”运算符之间的内容是否为真。非空字符串的真值是“真”,所以如果输入是 'west'
,那么它的结果就是:
if False or True or True:
不过,你想要的是
if item == 'north' or item == 'south' or item == 'east':
,或者说,更符合Python风格的是:
if item in ('north', 'south', 'east'):
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'
会被计算成 'east'
,这是因为 Python 在处理 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'
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
。