我正在尝试修改播放游戏“Rock,Paper,Scissors”的程序,以便观察数据验证。这里的目标是通过确保用户输入等于“摇滚”,“纸张”等来完成验证。或{'剪刀'在userMove
之前return
以下是我为用户输入创建的一项功能,其中我使用了while not in
来验证用户的输入,return
是有效输入还是{{ 1}}一个字符串,要求输入有效的信息。
问题:这是在此实例中验证的最有效方法吗?也许使用print
函数更有效?
ValueError
答案 0 :(得分:4)
你可以做的一件事就是使用一个集合,因为查找在集合中比在列表中更快,同样如评论所述,使用.lower()
会使你的代码更加健壮:
def userMove():
usersMove = input("Time to make your choice: ")
while usersMove.lower() not in {'rock', 'paper', 'scissors'}:
print("That is not a valid")
usersMove = input("Time to make your choice: ")
return usersMove
修改强>
另外,正如@utengr指出的那样,使用我以前的建议你也可以像这样转换你的代码,
def userMove():
while True:
usersMove = input("Time to make your choice: ")
if usersMove.lower() in {'rock', 'paper', 'scissors'}:
return usersMove
print("That is not a valid")
请注意,您的问题与性能有关。使用第二种解决方案不会以任何方式影响性能,这里的主要好处是可读性,因为您将代码压缩成一个块。
答案 1 :(得分:3)
您应该使用集合进行成员资格检查,因为它们比列表更快。此外,while true
比while some condition
[Python docs]更受欢迎。
def userMove():
while True:
usersMove = input("Time to make your choice: ")
if usersMove in {'rock', 'paper', 'scissors'}:
return usersMove
print("That is not a valid")
如果你不想像@scharette和@yklsga所建议的区分大小写,你也可以添加usersMove.lower()
。
答案 2 :(得分:2)
set.__contains__
和list.__contains__
的差异最多只有几纳秒。但用户输入速度的差异以毫秒或更多来衡量!所以最有效的方法是让用户输入一个字母。
def fast_user_move():
while True:
usersMove = input("Time to make your choice: ").lower().strip()
if usersMove and usersMove[0] in 'rps':
return usersMove[0]
print("That is not a valid choice")
要获得超有效的解决方案,请使用readchar库,用户只需按一个按钮不需要返回键!
from readchar import readchar
def super_fast_user_move():
print('Time to make your choice: [r]ock, [p]aper or [s]cissors?')
while True:
choice = readchar().lower()
if choice in 'rps':
return choice
print(f'{choice} is not a valid choice')
编辑:这种惊人的速度需要付出代价!如果用户尝试输入 STOP ,则输入将被解释为 Scissors ,这可能会导致各种危险。感谢@scharette的警告。
编辑2 :这是我做过的一些基准测试。正如您所看到的,这个版本的速度几乎是原版的200倍,以壁挂时间来衡量。
In [12]: %time userMove()
Time to make your choice: scissor
That is not a valid
Time to make your choice: scissors
CPU times: user 1e+03 µs, sys: 1 ms, total: 2 ms
Wall time: 6.02 s
Out[12]: 'scissors'
In [13]: %time super_fast_user_move()
Time to make your choice: [r]ock, [p]aper or [s]cissors?
CPU times: user 1 ms, sys: 0 ns, total: 1 ms
Wall time: 34.6 ms
Out[13]: 's'
(但应该注意我拼错了#34;剪刀"一次。)