我正在尝试为学校模拟评估创建公牛和奶牛游戏,并且我遇到了这行代码的问题
def BullsAndCows():
Guess= input("Please enter a 4 digit number, remember no duplicates!")
Guess = str(Guess)
while len(Guess) != 4:
Guess = input("IT has to be FOUR digits!")
Guess = str(Guess)
while Guess[0] == Guess[1] or Guess[0] == Guess[2] or Guess[0] == Guess[3] or Guess[1] == Guess[2] or Guess[1] == Guess[3] or Guess[2] == Guess[3]:
Guess = input("You can't use duplicates silly! Try another number!")
Guess = str(Guess)`
问题是如果我输入一个带有重复的4位数字,我就不能再输入非4位数而不输出此错误
回溯(最近调用最后一次):文件“python”,第64行,在文件“python”,第57行,在BullsAndCows中IndexError:字符串索引超出范围
第57行是while Guess[0] ==
......
第64行只是用于调用函数的BullsandCows()
。有谁知道这个问题?
当用户输入长度小于4的字符串时,会生成错误。在这种情况下,guess[3]
将超出范围。
如果你想检查你的输入是否符合条件,我会推荐一个由条件终止的while
:
import re
guess = ''
while not (guess.isdigit() \
and len(guess) == 4 \
and not re.search(r'(\d).*\1', guess)):
guess = input(...)
只要while
条件仍然是False
,循环继续运行。
guess.isdigit()
是一个字符串函数,用于检查字符串是否为数字。例如:
In [889]: '1234'.isdigit()
Out[889]: True
In [890]: '1234abc'.isdigit()
Out[890]: False
len(guess) == 4
,4
将检查字符串是否长度为True
。True
,则re.search
函数将应用正则表达式模式(如下所述)来搜索字符串中的重复项。如果存在重复,则返回匹配,评估为True
。否则,返回None
,这是False
。只要这三个条件中的任何一个都是False
,整个表达式就是False
(由于or
布尔逻辑如何工作)并且循环继续执行。
正则表达式细节
(\d) # digit (capture group)
.* # match 0 or more chars
\1 # reference 1st capture group
你的错误的原因是,一旦你通过了4位数的测试,即使输入发生变化,你也不会再这样做了。因此,如果您先输入1111,它会通过第一次测试(while len(Guess) != 4
),但不会通过第二次测试。如果你然后输入123,你会得到一个错误,因为输入只有3位数,而Guess[3]
提出了一个IndexError
您应该重构代码以在同一位置包含输入的所有测试,并且只有一个while
循环。像这样:
def BullsAndCows():
Guess= input("Please enter a 4 digit number, remember no duplicates!")
Guess = str(Guess)
(correct, message) = check_input(Guess)
while not correct:
Guess = input(message)
(correst, message) = check_input(Guess)
def check_input(guess):
if not guess.isdigit():
return (False, "Input a number")
if len(guess) != 4:
return (False, "The number should have 4 digits")
if guess[0] == guess[1] or ...
return (False, "No duplicates")
#other tests if necessary
return (True, "ok")
编辑:正如其他人所指出的那样,guess[0] == guess[1] or ...
既麻烦又容易出错。最好用更通用的东西替换它,如果你在输入中有4个,5个...... n个数字,它们同样有效。 AK47的解决方案(len(set(guess)) != len(guess)
)适用于此。由于首次使用的用户的语法有点模糊,以下是它的工作原理:
set(guess)
将输入转换为一组字符。一组只能有不同的元素,所以set('123')
= set('1233212')
= {'1', '2', '3'}
。len(set(guess)) == len(guess)
,这意味着guess
中的所有角色也在集合中;因此所有字符都是不同的。您可以通过删除while循环并使用1来简化您的方法,这将使程序保持运行直到方法中断
您可以使用len()
函数检查输入的值是否与4位数相匹配
您可以使用set()
构造函数构建输出的集合,这将删除重复项,然后将集合的len()
与原始输入的len()
进行比较
def BullsAndCows():
while True:
guess = str(input("Please enter a 4 digit number, remember no duplicates:"))
if len(guess) != 4:
print("It has to be FOUR digits")
continue
if len(set(guess)) != len(guess):
print("You cant enter duplicates silly! Try another number")
continue
print("No duplicates in number: {}".format(guess))
break
BullsAndCows()
>> Please enter a 4 digit number, remember no duplicates:
> 123
>> It has to be FOUR digits
>> Please enter a 4 digit number, remember no duplicates:
> 1111
>> You cant enter duplicates silly! Try another number
>> Please enter a 4 digit number, remember no duplicates:
> 1234
>> No duplicates in number: 1234