Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Other options instead of using try-except

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])
like image 984
Hal Avatar asked Feb 05 '23 00:02

Hal


2 Answers

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. 
like image 128
Mazdak Avatar answered Feb 06 '23 14:02

Mazdak


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])])
like image 27
Osman Mamun Avatar answered Feb 06 '23 13:02

Osman Mamun