Repeating Characters in a list/dictionary

Function

def update_hand(hand, word):
    word_list = list(word)
    for l in set(word_list):
        del hand[l]
    return hand

Output

Enter number of hands you would like to play: 4
e e a h x g r 

Play a word from your hand: hare
133
x g 
2

Should be xge

 When playing a word from my hand that has repeating letters in the hand (e e a h x g r). The function removes all instances of the letter e most likely due to the set() function.

Without it, I get a key error on the second pass of the loop.

Would you raise an exception for this or is there another way of doing this?

Thank you in advance for any help on this!

Thank you for showing your update_hand function, but we don’t need to see the user interface

Enter number of hands you would like to play: 4
e e a h x g r 

we need to see the code that calls update_hand.

  1. What is hand? Is it a list, a dict, a set, something else?

  2. What gets passed in as word?

Show us something like this:

hand = something goes here, but what?
something with update_hand(hand, what goes here?)    
print(hand)

Otherwise we’re guessing.

Below is the function call. As well as two other functions that deal with hand.


    num_hands = int(input("Enter number of hands you would like to play: "))
    hand = deal_hand(HAND_SIZE)
    (display_hand(hand))
    n = HAND_SIZE
    
    while num_hands >= 0:
        word = input("Play a word from your hand: ")
        word = word.lower()
        get_word_score(word, n)
        new_hand = update_hand(hand, word)
        n = len(new_hand)
        display_hand(new_hand)
        print(n)
def display_hand(hand):
    
    for letter in hand.keys():
        for j in range(hand[letter]):
             print(letter, end=' ')      # print all on the same line
    print()                           # print an empty line

def deal_hand(n):

hand={}
num_vowels = int(math.ceil(n / 3))

for i in range(num_vowels):
    x = random.choice(VOWELS)
    hand[x] = hand.get(x, 0) + 1

for i in range(num_vowels, n):    
    x = random.choice(CONSONANTS)
    hand[x] = hand.get(x, 0) + 1

return hand

hand appears to be a dictionary, with the value holding the number of letters. (You could possibly use a Counter a little bit more simply).

But that means when you wish to remove a character, you probably don’t want to blindly del the character from the dictionary. You probably want to check how many are left and subtract one from the count, only deleting if the count goes to zero. Otherwise if you use one of the characters in the word, you end up deleting all of that character from the hand.

Is something like this what you are describing? It doesn’t work so I know it isn’t right but I’m just trying different ways of doing it. This is my first time of working with dictionaries so thanks again for the help.

    hand_copy = hand.copy()
    for key, val in hand.items():
        if key in word:
            val -=1
            if val == 0:
                del hand_copy[key]
    return hand_copy

In the code above, assuming they’re integers, then changing val has no effect on the value remaining in hand_copy. Also, you only check if a letter is in a word, not if it’s in the word multiple times. I presume if the word is “feed”, you want to remove 2 "e"s.

Maybe something more like:

hand_copy = hand.copy()
for letter in word:
    if letter in hand_copy:
        hand_copy[letter] -= 1
        if hand_copy[letter] == 0:
            del hand_copy[letter]
    else:
        raise ValueError(f"Hand doesn't have all the letters of {word} to be removed")
return hand_copy

This seems to have worked. It may have unintended side effects down the line though since the docstring says it should not modify hand. I may need to make a copy like I had been trying to do. It seems that the problem with hand_copy is that every calling of this function returns all original letters(recopies) instead of only remaining letters because hand_copy was defined within the function definition. I may have to initialize it in the global scope if I run into any issues.

Thank you very much!

def update_hand(hand, word):
    word_copy = list(word)
    for l in word:
        if l in hand:
            hand[l] -= 1
    
            
    return hand