Reputation: 81
apologies in advance - I'm new to coding so this is probably a silly question!
I'm trying to scan a local text file (I downloaded the text from http://norvig.com/big.txt) and then read and print random lines from this file into a list.
However, I don't want to print any empty lines, just the lines that contain text.
So I've tried to use the following code:
import random
with open('C:\\big.txt', 'r') as f:
while True:
random_line_str = random.choice(f.readlines())
random_line_lst = random_line_str.split()
if random_line_lst != []:
print(random_line_lst)
break
So this works fine for lines that contain text. But it also occasionally spits out the following error:
Traceback (most recent call last):
File "C:\Python\lib\random.py", line 253, in choice
i = self._randbelow(len(seq))
File "C:\Python\lib\random.py", line 230, in _randbelow
r = getrandbits(k) # 0 <= r < 2**k
ValueError: number of bits must be greater than zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:/PycharmProjects/Testing/Test.py", line 5, in <module>
random_line_str = random.choice(f.readlines())
File "C:\Python\lib\random.py", line 255, in choice
raise IndexError('Cannot choose from an empty sequence')
IndexError: Cannot choose from an empty sequence
I haven't got a clue what's going on here to be honest...
Any ideas how I can avoid this happening and only return lines that contain text?
Cheers!
Upvotes: 0
Views: 1715
Reputation: 1057
I feel you can make use of strip method in this situation, because even if the line is empty you will still have the carriage return associated to that line. So you can check for the following condition
line.strip() != '' #checking if the line is empty by removing the Carriage return
with open('fdf.txt','r') as f:
for line in f:
if line.strip() != '' :
print(line)
Hope it helps.
Upvotes: 2
Reputation: 46027
print out if random_line_lst is not []
No, you are not checking for that. Rather you are checking whether list variable random_line_lst
do not exists in []
which is always true since []
is empty and nothing exists in it. So if random_line_lst not in []:
check is not correct.
Instead of you need to check:
if len(random_line_lst) > 0:
Or a short-cut (and better form) is to check
if random_line_lst:
Since empty lists are false.
Also, you can't call f.readlines()
always inside loop. You need to keep that lines in a variable before the loop starts, otherwise you will get an IndexError
next time the loop runs. The reason is in the first call of f.readlines()
the whole file is read, and in next call file position is already at end of file, so next read will return empty list, unless you seek to zero position of the file. For your case you can just move the readlines()
call out of loop.
with open('C:\\big.txt', 'r') as f:
lines = f.readlines()
while True:
random_line_str = random.choice(lines)
Upvotes: 2
Reputation: 14614
This line doesn't check if the item is an empty list, it checks if the item is in an empty list, which will always be false (meaning item not in []
will always be true):
if random_line_lst not in []:
What you can do is since bool([])
is False, just do:
if random_line_lst:
If you would likely to explicitly check for an empty list, use the !=
operator.
if random_line_lst != []:
Using the above, your code then becomes:
import random
with open('C:\\big.txt', 'r') as f:
while True:
random_line_str = random.choice(f.readlines())
random_line_lst = random_line_str.split()
if random_line_lst:
print(random_line_lst)
break
EDIT
For the random.choice
, the issue is you are repeatedly calling random.choice
on f.readlines()
. Readlines only returns each line on the first call, afterwards it will just return an empty sequence. random.choice
cannot select an item from an empty sequence. A better strategy is this:
import random
with open('C:\\big.txt', 'r') as f:
lines = f.readlines()
while True:
random_line_str = random.choice(lines)
random_line_lst = random_line_str.split()
if random_line_lst:
print(random_line_lst)
break
Or, if you can break away from randomness, use the following:
with open('C:\\big.txt', 'r') as f:
for line in f:
line_lst = line.split()
if line_lst:
print(line_lst)
break
Upvotes: 3