我不明白这个KeyError?
I don't understand this KeyError?
我正在做这个挑战,我的任务是编写一个刽子手游戏 - 我应该减少 set.The 游戏规则中的单词范围,你可以尝试 8 次太猜了,否则你会 lose.If 用户不止一次输入同一个字母会弹出一条消息,说明他已经这样做了 - 我已经使用集合作为处理这部分游戏的一种方式.下面是我的代码:
word_list = ["python", "java", "kotlin", "javascript"]
word = random.choice(word_list)
word_set = set(word)
hidden = []
for i in word:
hidden.append("-")
# print(hidden)
print("H A N G M A N")
count = 0
while(count < 8):
print()
print("".join(hidden))
guess = input("Input a letter: ")
if guess in word:
if guess not in word_set:
print("No improvements")
count += 1
else:
for i in range(len(word)):
if word[i] == guess:
print(word_set)
word_set.remove(word[i])
hidden[i] = word[i]
if word_set == set():
print()
print(word)
print("You guessed the word!")
print("You survived!")
else:
print("No such letter in the word")
count += 1
print("You are hanged!")
我面临的主要问题是一个错误告诉我 'a',特别是 'a' 是一个关键错误,如下所示:Traceback (most recent call last):
File "/Users/laipinhoong/Desktop/learnpython.py/learning.py", line 29, in <module>
word_set.remove(word[i])
KeyError: 'a'
The problem appears when the chosen word has the same letter more once.在这种情况下,由于您遍历了单词 (for i in range(len(word))
) 中的所有字母,您将尝试从集合 word_set
中删除该单词几次(与该字母在单词中出现的次数一样多)但是 word_set
将只有一次此字母,因为集合是唯一的集合。因此,在第二次尝试从 javascript
或 java
中删除 a
时,word_set.remove(word[i])
将失败,因为集合将不再包含此字母。
为了防止出错,尝试使用:
word_set.discard(word[i])
代替。在这种情况下,如果该字母存在,将被删除,如果不存在,则不会引发异常。
每次您选择单词中重复的字母时,您的关键错误都会发生。当你在 for i in range(len(word)):
循环中执行 word_set.remove(word[i])
并且 word
在多个 i
处有相同的字母时,当它击中第二个 [=13= 时会发生此键错误]对应单词中的那个字母。如果您在 python tutor.
中单步执行代码,这对您来说会更有意义
您需要了解您的代码的作用:
当您从 word_set.remove(word[i]) 中删除一个字符时。这将删除它,但在第二次迭代时它找不到该字符,因此它会抛出密钥错误,因为它找不到已删除的密钥。
尝试像这段代码一样添加一个 if 条件,以在删除之前检查密钥是否存在,如果不存在,实际上可以绕过,避免出现密钥错误
import random
word_list = ["python", "java", "kotlin", "javascript"]
word = random.choice(word_list)
print(word)
word_set = set(word)
hidden = []
for i in word:
hidden.append("-")
#print(hidden)
print("H A N G M A N")
count = 0
while(count < 8):
print()
print("".join(hidden))
guess = input("Input a letter: ")
if guess in word:
if guess not in word_set:
print("No improvements")
count += 1
else:
for i in range(len(word)):
if word[i] == guess:
if word in word_set:
word_set.remove(word[i])
hidden[i] = word[i]
if word_set == set(hidden):
print()
print(word)
print("You guessed the word!")
print("You survived!")
else:
print("No such letter in the word")
count += 1
print("You are hanged!")
您尝试多次删除同一个字母,因为您迭代了 word
- 而是迭代了它的一组字母。您还可以预先计算每个字母在字典中的位置,然后将其用于 "fill in the gaps",如下所示:
word = "javascript"
seen = set() # letters that were guessed get added here
letters = set(word) # these are the letters to be guessed
hidden = ["_" for _ in word] # the output
positions = {l:[] for l in letters } # a dictionary letter => positions list
for idx,l in enumerate(word): # add positions of each letter into the list
positions[l].append(idx)
print("H A N G M A N")
count = 0
while count < 8:
print()
print("".join(hidden))
# allow only 1-letter guesses
guess = input("Input a letter: ").strip()[0]
# if in seen it is a repeat, skip over the remainder of the code
if guess in seen:
print("Tried that one already.")
continue
# found a letter inside your word
if guess in positions:
# update the output list to contain this letter
for pos in positions.get(guess):
hidden[pos]=guess
# remove the letter from the positions list
del positions[guess]
else: # wrong guess
count += 1
print("No improvements: ", 8-count, "guesses left.")
# remember the seen letter
seen.add(guess)
# if the positions dictionary got cleared, we have won and found all letters
if not positions:
print(word)
print("You guessed the word!")
print("You survived!")
break
# else we are dead
if count==8:
print("You are hanged!")
输出:
__________
Input a letter:
j_________
Input a letter:
ja_a______
Input a letter:
java______
Input a letter:
javas_____
Input a letter:
javasc____
Input a letter:
javascr___
Input a letter:
javascri__
Input a letter:
javascrip_
# on bad inputs:
No improvements: 7 guesses left.
# on win
javascript
You guessed the word!
You survived!
# on loose
You are hanged!
Set.remove() 如果您要删除的项目不属于集合,则抛出 KeyError。
你的情况是word_set和单词的字母不一样造成的。
例如如果word = java,则word_set = (j, a, v)
并且由于您是在单词而不是 word_set 上循环,您的代码将尝试从 word_set 中删除字母 'a' 两次,这将导致 keyError
我正在做这个挑战,我的任务是编写一个刽子手游戏 - 我应该减少 set.The 游戏规则中的单词范围,你可以尝试 8 次太猜了,否则你会 lose.If 用户不止一次输入同一个字母会弹出一条消息,说明他已经这样做了 - 我已经使用集合作为处理这部分游戏的一种方式.下面是我的代码:
word_list = ["python", "java", "kotlin", "javascript"]
word = random.choice(word_list)
word_set = set(word)
hidden = []
for i in word:
hidden.append("-")
# print(hidden)
print("H A N G M A N")
count = 0
while(count < 8):
print()
print("".join(hidden))
guess = input("Input a letter: ")
if guess in word:
if guess not in word_set:
print("No improvements")
count += 1
else:
for i in range(len(word)):
if word[i] == guess:
print(word_set)
word_set.remove(word[i])
hidden[i] = word[i]
if word_set == set():
print()
print(word)
print("You guessed the word!")
print("You survived!")
else:
print("No such letter in the word")
count += 1
print("You are hanged!")
我面临的主要问题是一个错误告诉我 'a',特别是 'a' 是一个关键错误,如下所示:Traceback (most recent call last):
File "/Users/laipinhoong/Desktop/learnpython.py/learning.py", line 29, in <module>
word_set.remove(word[i])
KeyError: 'a'
The problem appears when the chosen word has the same letter more once.在这种情况下,由于您遍历了单词 (for i in range(len(word))
) 中的所有字母,您将尝试从集合 word_set
中删除该单词几次(与该字母在单词中出现的次数一样多)但是 word_set
将只有一次此字母,因为集合是唯一的集合。因此,在第二次尝试从 javascript
或 java
中删除 a
时,word_set.remove(word[i])
将失败,因为集合将不再包含此字母。
为了防止出错,尝试使用:
word_set.discard(word[i])
代替。在这种情况下,如果该字母存在,将被删除,如果不存在,则不会引发异常。
每次您选择单词中重复的字母时,您的关键错误都会发生。当你在 for i in range(len(word)):
循环中执行 word_set.remove(word[i])
并且 word
在多个 i
处有相同的字母时,当它击中第二个 [=13= 时会发生此键错误]对应单词中的那个字母。如果您在 python tutor.
您需要了解您的代码的作用:
当您从 word_set.remove(word[i]) 中删除一个字符时。这将删除它,但在第二次迭代时它找不到该字符,因此它会抛出密钥错误,因为它找不到已删除的密钥。
尝试像这段代码一样添加一个 if 条件,以在删除之前检查密钥是否存在,如果不存在,实际上可以绕过,避免出现密钥错误
import random
word_list = ["python", "java", "kotlin", "javascript"]
word = random.choice(word_list)
print(word)
word_set = set(word)
hidden = []
for i in word:
hidden.append("-")
#print(hidden)
print("H A N G M A N")
count = 0
while(count < 8):
print()
print("".join(hidden))
guess = input("Input a letter: ")
if guess in word:
if guess not in word_set:
print("No improvements")
count += 1
else:
for i in range(len(word)):
if word[i] == guess:
if word in word_set:
word_set.remove(word[i])
hidden[i] = word[i]
if word_set == set(hidden):
print()
print(word)
print("You guessed the word!")
print("You survived!")
else:
print("No such letter in the word")
count += 1
print("You are hanged!")
您尝试多次删除同一个字母,因为您迭代了 word
- 而是迭代了它的一组字母。您还可以预先计算每个字母在字典中的位置,然后将其用于 "fill in the gaps",如下所示:
word = "javascript"
seen = set() # letters that were guessed get added here
letters = set(word) # these are the letters to be guessed
hidden = ["_" for _ in word] # the output
positions = {l:[] for l in letters } # a dictionary letter => positions list
for idx,l in enumerate(word): # add positions of each letter into the list
positions[l].append(idx)
print("H A N G M A N")
count = 0
while count < 8:
print()
print("".join(hidden))
# allow only 1-letter guesses
guess = input("Input a letter: ").strip()[0]
# if in seen it is a repeat, skip over the remainder of the code
if guess in seen:
print("Tried that one already.")
continue
# found a letter inside your word
if guess in positions:
# update the output list to contain this letter
for pos in positions.get(guess):
hidden[pos]=guess
# remove the letter from the positions list
del positions[guess]
else: # wrong guess
count += 1
print("No improvements: ", 8-count, "guesses left.")
# remember the seen letter
seen.add(guess)
# if the positions dictionary got cleared, we have won and found all letters
if not positions:
print(word)
print("You guessed the word!")
print("You survived!")
break
# else we are dead
if count==8:
print("You are hanged!")
输出:
__________
Input a letter:
j_________
Input a letter:
ja_a______
Input a letter:
java______
Input a letter:
javas_____
Input a letter:
javasc____
Input a letter:
javascr___
Input a letter:
javascri__
Input a letter:
javascrip_
# on bad inputs:
No improvements: 7 guesses left.
# on win
javascript
You guessed the word!
You survived!
# on loose
You are hanged!
Set.remove() 如果您要删除的项目不属于集合,则抛出 KeyError。
你的情况是word_set和单词的字母不一样造成的。
例如如果word = java,则word_set = (j, a, v)
并且由于您是在单词而不是 word_set 上循环,您的代码将尝试从 word_set 中删除字母 'a' 两次,这将导致 keyError