Оператор if для проверки внутри оператора try в Python требует выполнения кода в случае возникновения исключения
Я немного озадачен здесь. Вот кусок кода Python:
try:
if parse[index+1][0] != "5":
individual_services+=[individual_services_cur]
individual_services_cur=[]
except IndexError:
warning("Reached end of file. No next element")
individual_services+=[individual_services_cur]
individual_services_cur=[]
В основном я хочу эти два действия (дополнение individual_services_cur
список к individual_services
список и очистка individual_services_cur
список), чтобы иметь место, если следующий элемент в parse
не "5" или, если он не существует (в основном это конец файла).
Мне интересно, есть ли более элегантный (возможно, даже, как говорится, "питонический") способ написания этого кода, например, без необходимости писать эти два действия дважды. Я не мог придумать ни одного хорошего решения с finally
или же else
заявления, и кажется, что я не могу избавиться от try
заявление, потому что, как только достигнут конец файла, IndexError
исключение неизбежно возникает.
5 ответов
Еще одна идея:
update_i_s = True
try:
update_i_s= parse[index+1][0] != "5"
except IndexError:
warning("Reached end of file. No next element")
finally:
if update_i_s:
individual_services.append([individual_services_cur]) if flag
individual_services_cur=[]
flag=True
требуется только в том случае, если в файле есть только одна строка, и ее нужно устанавливать только один раз в начале (поэтому не помещайте ее в какие-либо циклы).
РЕДАКТИРОВАТЬ:
Кстати, если есть возможность finally
блок может потерпеть неудачу, вы можете сделать что-то вроде этого:
try:
try:
update_i_s= parse[index+1][0] != "5"
except IndexError:
warning("Reached end of file. No next element")
finally:
if update_i_s:
individual_services.append([individual_services_cur]) if flag
individual_services_cur=[]
except Exception:
warning("failed to update individual_services")
raise
Вы можете использовать промежуточную переменную для выполнения необходимых проверок.
try:
value_to_check = parse[index+1][0]
except IndexError:
warning("Reached end of file. No next element")
value_to_check = None
finally:
if value_to_check != "5":
individual_services+=[individual_services_cur]
individual_services_cur=[]
Вы можете назначить переменную в обоих случаях, а затем проверить ее один раз.
badstuff = False
try:
if parse[index+1][0] != "5":
badstuff = True
except IndexError:
warning("Reached end of file. No next element")
badstuff = True
if badstuff:
individual_services+=[individual_services_cur]
individual_services_cur=[]
Если вас это устраивает, вы можете поставить if badstuff:
в finally
блок, в зависимости от того, что делает остальная часть вашего кода.
В качестве альтернативы, положить individual_services
вещи в функции, и вызывать его в обоих местах.
Как насчет
last = len(parse) - 1
if index == last or parse[index + 1][0] != "5":
individual_services.append(individual_services_cur)
individual_services_cur = []
Или мыслить нестандартно
if index + 1 not in (index for index, value in enumerate(parse) if value[0] == '5'):
individual_services+=[individual_services_cur]
individual_services_cur=[]
куда (index for index, value in enumerate(parse) if value[0] == '5')
является генератором, который выдает номер строки в каждой строке, у которой в качестве первого символа указано "5". Это эквивалентно этому:
def has_5s(p):
'''Yield line numbers that begin with a 5'''
for index, line in enumerate(p):
yield index if line[0] == '5'
if index + 1 not in has_5s(parse):
individual_services+=[individual_services_cur]
individual_services_cur=[]
Вы просто проверяете, есть ли следующий номер строки (line + 1
) является одним из этих номеров строк, полученных генератором. поскольку enumerate
и сам генератор ленив, это должно быть очень быстро.