views:

176

answers:

3

So far i have this, which prints out every word in my list, but i am trying to print only one word at random. Any suggestions?

def main():
    # open a file
    wordsf = open('words.txt', 'r')
    word=random.choice('wordsf')
    words_count=0
    for line in wordsf:
        word= line.rstrip('\n')
        print(word)
        words_count+=1      

    # close the file
    wordsf.close()
+4  A: 

Try:

print random.choice([x.rstrip() for x in open("words.txt")])

Note that this strips the '\n' from every line before choosing a random one; a better solution is left as an exercise for the reader.

Greg Hewgill
@Greg, `random.choice` does _not_ accept a generator argument (it wants an argument which supports `len`). If it did (or if you used a listcomp instead of the genexp), your code would print a random _line_, not a random _word_ from each line, as the OP asks for.
Alex Martelli
@Alex: Quite right thanks, corrected the use of a generator. I interpreted the question as asking for a random word chosen from a list of words given as one word per line.
Greg Hewgill
Never open a file without assigning it to a variable or you can't close it.
None
@None: That depends on your confidence in the Python reference-counting behaviour where the file will be closed when the last reference disappears. This, of course, is not necessarily true for all implementations of Python.
Greg Hewgill
@Greg, you were right in your interpretation of the question!
Alex Martelli
yes, you were right @Greg. Thank you all for your input
lm
+1  A: 

To print one random word per line, your loop could be:

for line in wordsf:
    word = random.choice(line.split())
    print(word)

If there are lines with nothing but whitespace, you also need to skip those:

for line in wordsf:
    if line.isspace(): continue
    word = random.choice(line.split())
    print(word)

The counting part you have seems to be correct, but unrelated to your question.

Edit: I see you meant something different in your Q (as other A's also intepreted): you want to choose a random line from the file, not a random word from each lines. That being the case, the other A's are correct, but they take O(N) auxiliary memory for a file of N lines. There's a nice algorithm due to Knuth to pick a random sample from a stream without knowing in advance how many items it has (unfortunately it requires generating N random numbers, so it's slower than the simpler one if you have enough memory for the latter... but it's still interesting to consider!-)...:

n = 0
word = None
for line in wordsf:
    n += 1
    if random.randrange(n) == 0:
        word = line
print(word.strip())

Basically, at each line n, we're picking it to replace the previous one (if any) with a probability of 1.0/n -- so the first time probability 1 (certainty), the second time probability 0.5, and so on. I'm doing the stripping only at the end as it would be a waste of effort to strip temporary choices that are later replaced; and I'm avoiding the division and floating point hassles by generating a random number with uniform probability between 0 and n-1 included (so the probability of that random number being 0 is 1/n) -- minor issues, but since they don't make the code any less clear, we might as well take care of them;-).

Alex Martelli
this does work, but it doesnt choose one word out of the entire file...and yes, the counting part is to print out how many words there are in the file
lm
A: 
import random
def main():
    wordsf = open('words.txt', 'r')
    words = [line.rstrip('\n') for line in wordsf]
    wordsf.close()

    random_number = random.randint(0, len(words)-1)
    random_word = words[random_number]
    print random_word

This works well, but if the file wordsf is too huge, then I think you'll start to encounter memory issues, but I think this should do fine for most cases

Hope this helps.

inspectorG4dget
this makes sense. i dont understand, though, why you have to use len()
lm
oh, and thank you for the help:)
lm
@inspectorG4dget: Python provides convenient functions such as `random.choice()` that can make this solution simpler.
Greg Hewgill
@Greg, ive been trying to use random.choice, but it hasnt been working out. what do you suggest i change in my mini program?
lm
@lm: Have you tried the solution offered in my answer to your question?
Greg Hewgill
@lm, len(list) tells you the length of "list". random.randint(a, b) returns a random integer between a and b inclusive, hence the len(words)-1. You should check the help on random.randint. Type the following onto the Python interpreter: import random; help(random.randint)
inspectorG4dget