2 votes

Je ne comprends pas cette KeyError ?

Je suis en train de faire ce défi où je suis chargé de coder un jeu de pendu - où je suis censé réduire la gamme de mots dans un ensemble.Les règles du jeu stipule que vous avez 8 essais trop deviner sinon vous perdez.Si l'utilisateur devait entrer la même lettre plus d'une fois un message apparaîtrait indiquant qu'il a déjà fait ainsi - J'ai utilisé des ensembles comme un moyen de gérer cette partie du jeu. Voici mon code :

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!")

Le principal problème auquel je suis confronté est une erreur qui me dit que "a" et seulement "a" en particulier est une erreur de clé qui se présente comme suit : Traceback (most recent call last): File "/Users/laipinhoong/Desktop/learnpython.py/learning.py", line 29, in <module> word_set.remove(word[i]) KeyError: 'a'

4voto

Gabip Points 6174

Le problème apparaît lorsque le mot choisi comporte plusieurs fois la même lettre. Dans ce cas, puisque vous itérez sur toutes les lettres du mot ( for i in range(len(word)) ) vous allez essayer de retirer ce mot plusieurs fois de l'ensemble word_set (autant que cette lettre apparaît dans le mot) mais word_set n'aura cette lettre qu'une seule fois puisque l'ensemble est une collection unique. Donc, dans la deuxième tentative de supprimer a de javascript o java , word_set.remove(word[i]) échouera car l'ensemble ne contiendra plus cette lettre.

Afin d'éviter cette erreur, essayez d'utiliser : word_set.discard(word[i]) à la place. Dans ce cas, la lettre sera supprimée si elle existe et sinon, aucune exception ne sera levée.

1voto

Patrick Artner Points 29630

Vous essayez d'enlever la même lettre plusieurs fois parce que vous itérez les word - itérer son ensemble de lettres à la place. Vous pourriez également précalculer les positions de chaque lettre de votre mot dans un dictionnaire et l'utiliser pour "remplir les trous" comme ceci :

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!")

Sortie :

__________
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!

0voto

Phillyclause89 Points 654

Votre erreur principale va se produire chaque fois que vous choisissez une lettre qui est répétée dans le mot. Lorsque vous faites word_set.remove(word[i]) à l'intérieur d'un for i in range(len(word)): et la word a la même lettre à plusieurs endroits i cette erreur de clé se produira lorsqu'elle atteindra la seconde i correspondant à cette lettre dans le mot. Cela aura plus de sens pour vous si vous parcourez votre code de la manière suivante tuteur python .

0voto

Jaskaran Singh Points 421

Vous devez comprendre ce que fait votre code :

Lorsque vous supprimez un caractère de word_set.remove(word[i]). Cela le supprime, mais à la deuxième itération, il ne trouve pas le caractère et lance l'erreur de clé car il ne peut pas trouver la clé qui a déjà été supprimée.

Essayez d'ajouter une condition if comme dans ce code pour vérifier si la clé existe avant de la supprimer. Si elle n'existe pas, elle est pratiquement contournée, ce qui vous évitera une erreur de clé.

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!")

0voto

Set.remove() génère une KeyError si l'élément que vous supprimez ne fait pas partie de l'ensemble.

Dans votre cas, cela est dû au fait que le mot_set et le mot n'ont pas les mêmes lettres.

Par exemple, si word = java, alors word_set = ( j, a, v)

Et puisque vous bouclez sur le mot au lieu de word_set, votre code va tenter de supprimer la lettre 'a' deux fois de word_set, ce qui entraînera une keyError.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X