Другие варианты вместо использования try-except

когда строка 2 в текстовом файле имеет "nope", она будет игнорировать строку и продолжит следующую. Есть ли другой способ написать это без использования try and except? Могу ли я использовать оператор if else для этого?

пример текстового файла:

0 1 
0 2 nope
1 3 
2 5 nope

код:

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])

5 ответов


Да, вы можете использовать str.endswith() метод проверки трейлинга линий.

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)])

обратите внимание, что при использовании with инструкция для открытия файла вам не нужно закрывать файл явно файл будет автоматически закрыт в конце блока.

другой, но более оптимизированный подход для решения этой проблемы-использовать понимание списка, чтобы отказаться от добавления в список на каждой итерации и воспользоваться его производительностью по сравнению с регулярная петля.

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'))]

обратите внимание, что, поскольку ваш код подвержен исключениям из-за преобразования строк в целое число и разделения строк и т. д. Лучше использовать try-except, чтобы предотвратить возможные исключения кода и правильно их обрабатывать.

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

другой и все же Питонический подход-использовать csv модуль для чтения файла. В этом случае вам не нужно разбивать строки и / или использовать 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. 

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])])

Если nope может быть не только в конце строки вы можете использовать это

with open('e.txt') as e:
    alist = [line.split() for line in e if 'nope' not in line]

print(alist)

могу ли я использовать оператор if else для этого?

вы должны использовать операторы if-else, а не исключения, для управления потоком в случае обычных "событий", которые вы ожидаете. Это общее "правило" во многих языках, Я думаю, что Python не вызывает исключения здесь, Python is исключение здесь, но, надеюсь, не в таких случаях.

следуя вашему коду, но без вызова line.split() each time, извлекающ попробуйте-за исключением и с использованием надлежащего условия в 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])])

и, конечно, вы можете отрицать условие и избегать continue:

if len(splitted) <= 2 or splitted[2] != 'nope':
    alist.append([int(splitted[0]), int(splitted[1])])

что показывает (другую) слабость в случае, если у вас меньше 2 элементов. Здесь вы можете использовать попробовать: исключение в этом случае говорит вам, что формат ввода неправильный (потому что вы ожидаете, по крайней мере, 2 элемента, кажется), поэтому вы должны отклонить ввод и предупредить пользователя. Кроме того, вы можете перехватить ValueError если эти 2 элемента не являются целыми числами.

кроме того, если ваш вклад может содержать лишние пробелы, вы можете использовать что-то вроде splitted[2].strip().


показания на SO / SE о попытке-кроме материи.


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)])