Другие варианты вместо использования try-кроме - PullRequest
0 голосов
/ 20 мая 2018

Когда строка 2 в текстовом файле имеет значение «nope», она игнорирует эту строку и продолжает следующую.Есть ли другой способ написать это без использования try и кроме?Могу ли я использовать оператор 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 ]

0 голосов
/ 20 мая 2018

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

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

print(alist)
0 голосов
/ 20 мая 2018

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

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

Следуя вашему коду, но не вызывая line.split() каждый раз, удаляя попытку-исключая и используя правильное условие в 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 элементов.Здесь вы можете использовать try : исключение в этом случае говорит вам, что формат ввода неправильный (кажется, вы ожидаете как минимум 2 элемента), поэтому вы должны отклонить ввод и предупредить пользователя.Кроме того, вы можете перехватить ValueError, если эти 2 элемента не являются целыми числами.

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


Чтения в SO / SE по поводу вопроса, за исключением вопроса.

0 голосов
/ 20 мая 2018
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])])
0 голосов
/ 20 мая 2018
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)])
0 голосов
/ 20 мая 2018

Да, вы можете использовать метод 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'))]

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

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

Другой и все же подход Pythonic заключается в использовании модуля 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. 
...