It could be as simple as:
import random
print(random.choice(open("WordsForGames.txt").readline().split()))
The words are read from the first line of the file and converted into an array, then a random choice is made from that array.
If the words are instead on separate lines (or spread across lines), use read() instead of readline().
It could be as simple as:
import random
print(random.choice(open("WordsForGames.txt").readline().split()))
The words are read from the first line of the file and converted into an array, then a random choice is made from that array.
If the words are instead on separate lines (or spread across lines), use read() instead of readline().
Your line words = open("../WordsForGames.txt") does not read the file, it just opens it for reading or possibly writing if you add additional flags.
You need to read the line or lines using readlines(), for example, and then most likely split the words into a list and then randomly select one of the words. Something like this:
import random
# get the first line if this is the one with the words words
lines = open("../WordsForGames.txt").readlines()
line = lines[0]
words = line.split()
myword = random.choice(words)
Selecting a random word from text file?
python - Getting a random word from a text file - Stack Overflow
Pick a random big word from a list of words using Python - Code Review Stack Exchange
How to select a random word from a txt file in python version 3.4? - Stack Overflow
Hi, I'm tying to select a random word from a text file, display it, and then select another random word(and so on and so forth). I'm brand new to coding so VERY specific answers would be appreciated.
import random
def generate_the_word(infile):
random_line = random.choice(open(infile).read().split('\n'))
return random_line
def main():
infile = "words.txt"
print(generate_the_word(infile))
main()
Your for loop is iterating over every line in the file and indexing into that line. You should also take advantage of Python's context managers, which take care of opening and closing files for you. What you want is to load all the lines:
with open(infile) as f:
contents_of_file = f.read()
Your second problem is that you aren't properly indexing into those lines with randrange. You want a range between 0 and the max number of lines:
lines = contents_of_file.splitlines()
line_number = random.randrange(0, len(lines))
return lines[line_number]
You also need to import the random module before this will run.
Your whole program would look like:
import random
def generate_the_word(infile):
with open(infile) as f:
contents_of_file = f.read()
lines = contents_of_file.splitlines()
line_number = random.randrange(0, len(lines))
return lines[line_number]
def main():
print(generate_the_word("Filename.txt"))
main()
You should also note that reading the file every time is inefficient; perhaps read it once and then pick lines from that. You could, for instance, read it in the main function and pass its already-read values to the generate_the_word function.
Comments
- Python functions are written in
snake_case. - You could use function parameters for word length and filename.
- You could use iterators and generators to avoid loading the whole file into memory.
- If you read the file line by line, you need to take care with the trailing newline character:
len("test\n")is5.
Refactoring
Here's a way to rewrite your function. Thanks to a generator, the script only loops once over every line:
import random
def goal_word(min_length=7, filename="words.txt"):
with open(filename) as wordbook:
words = (line.rstrip('\n') for line in wordbook)
large_words = [word for word in words if len(word) >= min_length]
return random.choice(large_words)
print(goal_word(7))
# evening
print(goal_word(15))
# circumnavigations
Optimization
@etchesketch commented that rstrip is called on every line even though it's only needed for one word. Here's a variation:
import random
def goal_word(min_length=7, filename="words.txt"):
min_line_length = min_length + 1
with open(filename) as wordbook:
large_words = [line for line in wordbook if len(line) >= min_line_length]
return random.choice(large_words).rstrip('\n')
print(goal_word(7))
# jauntily
print(goal_word(15))
# fundamentalists
On a dictionary of English words (/usr/share/dict/american-english), this function is 3 times faster than the previous one.
Exception handling
In the above examples, goal_word(30) fails with IndexError: Cannot choose from an empty sequence. There's no indication that the desired length is too long.
Before calling random.choice, the script could simply check that large_words isn't empty:
import random
def goal_word(min_length=7, filename="words.txt"):
min_line_length = min_length + 1
with open(filename) as wordbook:
large_words = [line for line in wordbook if len(line) >= min_line_length]
if large_words:
return random.choice(large_words).rstrip('\n')
else:
raise ValueError("No word found with at least %s characters." % min_length)
print(goal_word(7))
# jauntily
print(goal_word(15))
# insurrectionist's
print(goal_word(30))
# ValueError: No word found with at least 30 characters.
You don't need to read the whole file in at once nor use random.choice() if you use the reservoir-sampling algorithm. (This is the algorithm used in fortune on Unix!)
The algorithm is based on the idea that you select later samples based on a decreasing probability.
#!/usr/bin/python
import random
from itertools import ifilter
_MAX_LEN = 6
def goalword():
with open("words.txt") as fd:
for linenum, line in enumerate(ifilter(lambda x: len(x)-1 > _MAX_LEN, fd)):
if random.uniform(0, linenum+1) <= 1:
ret = line
return ret.strip()
print goalword()
I based this on the Perl implementation from Perl Faq #5, which I'm more familiar with:
srand;
rand($.) < 1 && ($line = $_) while <>;
Since in Perl 0 <= rand(X) < X, whereas in Python, 0 <= random(0, X) <= X "depending on floating-point rounding in the equation a + (b-a) * random()", I've made my comparison inclusive (<=) to make sure the first line is always true.
If you look at Wikipedia's sample implementation, they just use randint(), so here is a modification to do that:
#!/usr/bin/python
from itertools import ifilter
from random import randint
_MAX_LEN = 6
def goalword():
with open("words.txt") as fd:
for linenum, line in enumerate(ifilter(lambda x: len(x)-1 > _MAX_LEN, fd)):
if randint(0, linenum) < 1:
ret = line
return ret.strip()
print goalword()
Again, I make sure the first randint() is always true, otherwise a single line file might occasionally get no result.
For a reduce() implementation,
def goalword():
with open("words.txt") as fd:
return reduce(lambda old, (i, new): new if randint(0, i) < 1 else old,
enumerate(ifilter(lambda x: len(x)-1 > _MAX_LEN, fd))).strip()
print goalword()
Turns out, though, that reduce() isn't necessarily faster:
# for loop
print(timeit.timeit("goalword0()", setup="from __main__ import goalword0; import random; random.seed(42)", number=100, timer=time.clock))
# reduce
print(timeit.timeit("goalword1()", setup="from __main__ import goalword1; import random; random.seed(42)", number=100, timer=time.clock))
45.05 # for loop
49.17 # reduce
Note:
If you're picking more than one word from each execution, reading the whole file into a list will likely be more time efficient.
If you're just picking one word, however, this implementation is the most time and space efficient since you read the whole file once, but only retain one word in memory.
"In theory there is no difference between theory and practice. In practice there is."
I've tested this against a read-the-whole-file implementation:
def goalword():
with open("words.txt") as fd:
words = filter(lambda x: len(x)-1 > _MAX_LEN, fd)
return random.choice(words).strip()
It is significantly faster:
45.04 # For loop
7.14 # random.choice()
My word list is not insignificant:
$ curl -O https://raw.githubusercontent.com/dwyl/english-words/master/words.txt
$ wc -l words.txt
466544 words.txt
My guess this is due to the overhead of the extra python opcode operations in the for loop vs filter being implemented in native C. i.e., we stay out of the interpreter for more of the work in the random.choice() implementation.
So, while not necessarily always faster, if you need to avoid loading the whole list into memory, reservoir sampling is what you want.
hey guys. i'm doing some homework. we are to write hangman. it seems like lots of people do it as there is tons of ways to do it. im working on my own, and i'm having trouble pulling a random line over from my wordList.txt I get no errors, but it's pulling over an empty string. here is mycode:
with open('wordList.txt', 'r') as wordList: #open the file in readMode
i=0
for lines in wordList: #count the lines of the file to create a range for randint()
i+=1
wordSelect = random.randint(0,i) #select a number within range of the number of lines in my wordList.txt
secretWord = wordList.readlines(wordSelect) #read the line(which is one word long)
print(wordSelect) #debuging: shows random number has been chosen
print(secretWord) #debugging prints"[]"edit: thanks to u/commandlineuser for pointing out that after the for loop, there are no more lines to read. i updated my code to:
with open('wordList.txt', 'r') as wordList: #open the file in readMode
i=0 #thanks to /u/commandlineuser for reminding me that after the loop, there are no more lines to read
for lines in wordList: #count the lines of the file to create a range for randint()
i+=1
with open('wordList.txt', 'r') as wordList: #reopen the file
wordSelect = random.randint(0,i) #use i from the previous open
secretWord = wordList.readlines()[wordSelect] #get the line(which is one word Title. I’m working on a project, all that’s left is it needs to read a random/mostly random line from a text file, but it turns out I don’t know how to code that…
The way I would approach this problem is to read through the text file, appending every word to a list (you'll have to write some basic logic involving identifying words, strip() may come in handy here)
You can then pass that list into your get_word function and use random.choice(yourList) to obtain a random word in the text file.
this is my first answer rsrs! Well, you can use a random lib for this:
def get_word(word_list):
import random
print(random.choice(word_list))
This function now get a randomly word in the list. It's that : )
I want to generate a random word of a specific length. I found a python module called random-word and this is my code.
from random_word import RandomWords
r = RandomWords()
# Return a single random word
r.get_random_word()
result = None
while result is None:
try:
word1 = r.get_random_word()
print (word1)
if len(word1) == 5:
result = True
except:
print ('There was a problem')
# other code that uses result but is not involved in getting it
print (word1)
print (len(word1))It works perfectly fine, but it's very slow. It takes about 10 to 15 seconds to run until it finds a word of that length. Does anybody have a better way of doing this? Another way I thought was to maybe have a dictionary file and iterate through that. The reason I don't like that approach is I don't really like the idea of having to have a file on the machine. Also if it iterates through the file it won't be random.
Any suggestions appreciated.
Thanks
Hi there, I've been looking everywhere for a solution to this, however I can't find an answer written strictly in C. I have been trying to recreate Hangman in order to test myself, and I have a word file which I plan on expanding later. I would like to pick a random word from this list to use, but I can only figure out how to pick the first word. Any help would be really appreciated!