[Tutor] Re: problem writing random_word function

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Mon Jul 19 19:59:37 CEST 2004



> I've rewritten the function as below and everything seems to work
> correctly.
>
> def random_word(word_length):
>     """Returns a random word of length word_length"""
>     import random
>     f = open("hangman_words.txt","r")
>     word_list = []
>     while 1:
>         word = f.readline()
>         word = word.strip()
>         if word == "":
>             break
>         elif len(word) == word_length:
>             word_list = word_list + [word]
>     f.close()
>     return word_list[random.randint(0,(len(word_list)-1))]


Hi Matt,

Looks ok!  Here are some suggestions to make the code more "Pythonic"
(whatever that means... *grin*).


There's a slightly more idiomatic way of writing that loop --- instead of
using a 'while' loop, we're allowed to use a 'for' loop across a file:


    for word in file:
        word = word.strip()
        ...

This works because files are 'iterable' in the same way that lists or
sequences are iterable.  Using the 'for' construct will cut down on a few
lines, and also remove the need for the an explicit 'break' statement to
stop the loop.


Using the 'for' loop approach also ends up being less bug prone.  In the
original code, if there were an empty line in the middle of the
'hangman_words.txt' file, then the loop would break prematurely.
Rewriting the loop as:

     while 1:
         word = f.readline()
         if word == "":
             break
         ...

that is, pushing the 'if word == "": ...' test up a bit, will also fix
that potential problem.



Also, as you're scanning for new candidate words for selection, you may
want to use the 'append()' method to add new words into the 'word_list'.
What you have right now:

    word_list = word_list + [word]

constructs a whole new word_list out of the original word_list.  It's a
little less expensive to do an 'append':

    word_list.append(word)

More importantly, though, is that Python programmers will probably
recognize the 'append' idiom for adding new elements onto a list, as
opposed to using the '+' approach.




Finally, there's a function in the 'random' module that knows how to
choose a random element off a list, so the last expression:

>     return word_list[random.randint(0,(len(word_list)-1))]

can be slightly simplified.  See:

    http://www.python.org/doc/lib/module-random.html#l2h-1149



More information about the Tutor mailing list