Reputation: 372
When line 2 in the text file has 'nope' then it will ignore the line and continue the next one. Is there another way to write this without using try and except? Can I use if else statement to do this?
Example of text file:
0 1
0 2 nope
1 3
2 5 nope
Code:
e = open('e.txt')
alist = []
for line in e:
start = int(line.split()[0])
target = int(line.split()[1])
try:
if line.split()[2] == 'nope':
continue
except IndexError:
alist.append([start, target])
Upvotes: 9
Views: 7325
Reputation: 2882
with open('e.txt', 'r') as f:
alist = []
for line in f:
words = line.split()
if len(words) > 2 and words[2] == 'nope':
continue
else:
alist.append([int(words[0]), int(words[1])])
Upvotes: 3
Reputation: 9671
Can I use if else statement to do this?
You should use if-else statements, not exceptions, to control the flow in case of ordinary “events” which you expect. This is common “rule” in many languages, I think Python doesn't raise an exception here, Python is an exception here, but hopefully not in cases like this.
Following your code but without calling line.split()
each time, removing the try-except and using a proper condition in the if
:
alist = []
with open('e.txt') as e:
for line in e:
splitted = line.split()
if len(splitted) > 2 and splitted[2] == 'nope':
continue
else:
alist.append([int(splitted[0]), int(splitted[1])])
And of course you can negate the condition and avoid the continue
:
if len(splitted) <= 2 or splitted[2] != 'nope':
alist.append([int(splitted[0]), int(splitted[1])])
Which shows (another) weakness in case when you have less than 2 elements. Here you could use try: the exception in this case tells you that the input format is wrong (because you expect at least 2 elements, it seems), so you have to reject the input and warn the user. Also, you could intercept ValueError
if those 2 elements aren't integers.
Moreover, if your input is allowed to contain extra spaces, you can use something like splitted[2].strip()
.
Readings on SO/SE about the try-except matter.
Exceptions
are actually exceptional.”Upvotes: 1
Reputation: 107287
Yes, you can use str.endswith()
method to check the trailing of the lines.
with open('e.txt') as f:
for line in f:
if not line.endswith(('nope', 'nope\n')):
start, target = line.split()
alist.append([int(start), int(target)])
Note that when you use a with
statement to open a file you don't need to close the file explicitly the file will be closed automatically at the end of the block.
Another but more optimized approach to solve this is to use a list comprehension in order to refuse appending to the list at each iteration and benefit from its performance compare to a regular loop.
with open('e.txt') as f:
alist = [tuple(int(n) for i in line.split()) for line in f if not line.endswith(('nope', 'nope\n'))]
Note that still, since your code is exception prone because of converting strings to integer and splitting the lines, etc. It's better to use a try-except in order to prevent your code from possible exceptions and handle them properly.
with open('e.txt') as f:
for line in f:
if not line.endswith(('nope', 'nope\n')):
try:
start, target = line.split()
except ValueError:
# the line.split() returns more or less than two items
pass # or do smth else
try:
alist.append([int(start), int(target)])
except ValueError:
# invalid literal for int() with base 10
pass # or do smth else
Another and yet Pythonic approach is to use csv
module for reading the file. In that case you don't need to split the lines and/or use str.endswith()
.
import csv
with open("e.txt") as f:
reader = csv.reader(f, delimiter=' ')
alist = [(int(i), int(j)) for i, j, *rest in reader if not rest[0]]
# rest[0] can be either an empty string or the word 'nope' if it's
# an empty string we want the numbers.
Upvotes: 6
Reputation: 1840
alist = []
with open('e.txt') as fin:
for line in fin:
rest_line, nope = line.strip().rsplit(' ', 1)
if nope != 'nope':
alist.append([int(rest_line), int(nope)])
Upvotes: 0
Reputation: 7412
If nope
can be not only at the end of the line you can use this
with open('e.txt') as e:
alist = [line.split() for line in e if 'nope' not in line]
print(alist)
Upvotes: 1