错误验证使用'而不是'

时间:2017-10-30 21:37:34

标签: python

我正在尝试修改播放游戏“Rock,Paper,Scissors”的程序,以便观察数据验证。这里的目标是通过确保用户输入等于“摇滚”,“纸张”等来完成验证。或{'剪刀'在userMove之前return

以下是我为用户输入创建的一项功能,其中我使用了while not in来验证用户的输入,return是有效输入还是{{ 1}}一个字符串,要求输入有效的信息。

问题:这是在实例中验证的最有效方法吗?也许使用print函数更有效?

ValueError

3 个答案:

答案 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 truewhile 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;剪刀"一次。)