[Tutor] trouble with list.remove() loop

Peter Otten __peter__ at web.de
Tue Sep 28 18:03:34 CEST 2010


D Ryan (2) wrote:

> Hello all,
> I am currently trying to write a program which can find the solution to a
> game of hangman.
> In a part of the program, a user inputs a letter, a tester tells him if
> the word contains that letter, and then if the answer is no, all words
> containing that letter are removed from the list of remaining candidates.
> However, the code I've written seems to remove some, but not all the words
> containing the letter. Strangely though, if i run it a few more times it
> gets some of the ones it missed the 1st time round, untill after enough
> iterations it gets all of them. I cant understand why it doesnt remove all
> of them the first time round. I have cut the offending code and formatted
> it to work on its own, and also to fit into a relatively short email.
> 
> # A sample list of words, one of which is the answer.
> candidates = ["abacus","amazing",
>               "ozimandias",
>               "a","alphanumeric",
>               "functioning"]
> 
> # In the following code, the user has guessed the letter 'a',
> # and the tester has told him that the letter 'a' is not in the word.
> 
> user_guess="a"
> tester_response="no"
> 
> # The following code should eliminate all words which contain the letter
> # 'a', leaving only the word 'functioning' in the list
> 
> if tester_response in ("No","no","n","N","NO"):
>     for word in candidates:
>         if user_guess in word:
>             print word, "removed.."
>             candidates.remove(word)
> print candidates
> 
> Running once gives this output
> 
> abacus removed..
> ozimandias removed..
> alphanumeric removed..
> ['amazing', 'a', 'functioning']
> 
> But if i run it again it successfully removes 'amazing, and the next time
> it removes 'a', leaving the correct answer. I'm perplexed by this strange
> behaviour and would be most appreciative of any help. I'm very new to
> python so apologies for any formatting/style errors, and also for the
> simplicity of the problem.

I'd like to point out a robust method to avoid such pitfalls: create a new 
list instead of modifying the old one:

old_candidates = candidates
candidates = []
for word in old_candidates:
    if user_guess in word:
        print word, "removed"
    else:
        candidates.append(word)
print candidates

Often you can simplify that to a list comprehension like

candidates = [word for word in candidates if user_guess not in word]

Peter



More information about the Tutor mailing list