当检查是否在空字符串变量中填充了某些字符时,该表达式始终被评估为true。如果新创建的字符串值为空,则应为false,它不包含任何字符,更不用说要检查的字符了。
当我硬编码不是检查表达式的字符的随机字符时,将被评估为false。
difficulty = ''
while difficulty not in 'EMH':
print('Enter difficulty: E - Easy, M - Medium, H - Hard')
difficulty = input().upper()
我希望看到调试器进入while循环。实际发生的情况是它继续经过while块而没有执行。
答案 0 :(得分:6)
任何字符串中都存在一个空字符串。因此,当difficulty not in 'EMH'
等于False
时,您的条件difficulty
将得出''
;因此while循环的主体将不会执行。
In [24]: '' not in 'EMH'
Out[24]: False
In [33]: '' in 'EMH'
Out[33]: True
一个更好的方法可能是通过EMH
将字符串list('EMH')
转换为列表,这样EM
或EH
之类的字符或空字符不会中断您的循环,或者避免从头开始
还有@Blckknght建议,一个更好的选择是使用None
的默认值来解决问题。
In [3]: difficulty = None
In [4]: while difficulty not in list('EMH'):
...: print('Enter difficulty: E - Easy, M - Medium, H - Hard')
...: difficulty = input().upper()
...:
Enter difficulty: E - Easy, M - Medium, H - Hard
A
Enter difficulty: E - Easy, M - Medium, H - Hard
B
Enter difficulty: E - Easy, M - Medium, H - Hard
C
Enter difficulty: E - Easy, M - Medium, H - Hard
EM
Enter difficulty: E - Easy, M - Medium, H - Hard
E
In [5]:
答案 1 :(得分:6)
我认为您需要使用列表而不是字符串:
difficulty = ''
while difficulty not in ['E','M','H']:
print('Enter difficulty: E - Easy, M - Medium, H - Hard')
difficulty = input().upper()
答案 2 :(得分:2)
这是do-while循环条件的好例子。但是,python没有。请检查以下样式是否适合您:
while True:
print('Enter difficulty: E - Easy, M - Medium, H - Hard')
difficulty = input().upper()
if difficulty not in 'EMH': #or in ['E', 'M', 'H']
continue
else:
#do some logic
break
我喜欢@Emmet B的建议,它在循环而不是字符串中使用['E','M','H']。这也很有意义,因为您希望将其中一个字符作为输入而不是字符集。
答案 3 :(得分:2)
如果您倾向于生活在Python的前沿,那么您可能有兴趣尝试使用当前正在开发的Python 3.8(但可以使用alpha版本)。赋值表达式是一个颇具争议的新功能(在PEP 572中引入),它使您可以使用:=
在另一个表达式的中间进行赋值。
您正在执行的循环可以利用这种分配一次性完成输入和值检查,而无需在进入循环之前为difficulty
分配虚假的初始值。
请注意,您可能仍想使用列表而不是在右边的字符串上使用not in
,因为后者进行子字符串检查,而不是严格的序列成员资格测试。像difficulty not in 'EMH'
这样的子字符串测试将为空字符串或多字母输入'EM'
,'MH'
和'EMH'
带来意外的结果。如果您可能在某处使用不同的难度字符串作为字典键(例如,查找随难度设置而变化的统计信息),则可以直接测试输入是否是字典中的键,而不是构建单独的列表。
prompt = 'Enter difficulty: E - Easy, M - Medium, H - Hard\n'
while (difficulty := input(prompt).upper()) not in ['E', 'M', 'H']:
pass # or maybe: print("I'm sorry, I didn't understand that.")
# you can use `difficulty` down here
请注意,尽管您可以在此处 使用赋值表达式,但这并不是一个好主意,只是为了避免初始化变量。您最终将很多不同的东西捆绑在一起(while
,input
和upper
调用,:=
的赋值和{{1}测试),很容易对正在发生的事情感到困惑。确实,在上面的示例中,我最终创建了一个 different 变量(not in
),因为否则该行太长了。
答案 4 :(得分:1)
已经提到了解决方案(恕我直言,使用list
可以解决问题,并将变量初始化为None
很干净,恕我直言),但是有很多不同的方法可以做到这一点(尽管Zen of Python的规则#13。
我还没有提到的一个建议是在while表达式中使用一个单独的布尔值,因此您不必使用任意无效值来初始化difficulty
变量,并且不需要其他{ {1}} / continue
/ break
/ else
语句:
pass