У меня есть понимание списка в Python, в котором каждая итерация может вызывать исключение.
Например , если у меня есть:
eggs = (1,3,0,3,2)
[1/egg for egg in eggs]
Я получу ZeroDivisionError
исключение в 3-м элементе.
Как я могу обработать это исключение и продолжить выполнение понимания списка?
Единственный способ, который я могу придумать, - это использовать вспомогательную функцию:
def spam(egg):
try:
return 1/egg
except ZeroDivisionError:
# handle division by zero error
# leave empty for now
pass
Но мне это кажется немного громоздким.
Есть ли лучший способ сделать это в Python?
Примечание. Это простой пример (см. « Например » выше), который я придумал, потому что мой реальный пример требует некоторого контекста. Я не заинтересован в том, чтобы избежать ошибок деления на ноль, а в обработке исключений в понимании списка.
python
exception
list-comprehension
Натан Феллман
источник
источник
[1/egg except ZeroDivisionError: None for egg in (1,3,0,3,2)]
. Но он все еще в черновом режиме. Я чувствую, что это не будет принято. Выражения Imho могут стать слишком запутанными (проверка нескольких исключений, наличие более сложных комбинаций (несколько логических операторов, сложные понимания и т. Д.)ndarray
с соответствующими настройками вnp.seterr
. Это приведет к1/0 = nan
. Но я понимаю, что это не распространяется на другие ситуации, в которых возникает такая необходимость.Ответы:
В Python нет встроенного выражения, которое позволяет игнорировать исключение (или возвращать альтернативные значения & c в случае исключений), поэтому невозможно, буквально говоря, «обрабатывать исключения в понимании списка», потому что понимание списка является выражением содержащие другое выражение, ничего более (т. е. никаких операторов, и только операторы могут перехватывать / игнорировать / обрабатывать исключения).
Вызовы функций являются выражениями, а тела функций могут включать в себя все нужные вам операторы, поэтому делегирование оценки подверженного исключениям подвыражения функции, как вы заметили, является одним из возможных обходных путей (другие, когда это возможно, проверки значений, которые могут вызвать исключения, как это также предлагается в других ответах).
Правильные ответы на вопрос «как обрабатывать исключения в понимании списка» все выражают часть всей этой истины: 1) буквально, то есть лексически В самом понимании, вы не можете; 2) практически вы делегируете задание функции или проверяете значения, подверженные ошибкам, когда это возможно. Таким образом, ваше неоднократное утверждение о том, что это не ответ, является необоснованным.
источник
[x[1] for x in list except IndexError pass]
. Не смог интерпретатор создать временную функцию, чтобы попробоватьx[1]
?Я понимаю, что этот вопрос довольно старый, но вы также можете создать общую функцию, чтобы упростить такие вещи:
Затем, насколько вы понимаете:
Вы, конечно, можете сделать функцию дескриптора по умолчанию как хотите (скажем, вы бы предпочли по умолчанию вернуть «None»).
Надеюсь, это поможет вам или другим будущим зрителям этого вопроса!
Примечание: в python 3 я бы сделал только ключевое слово аргумента handle и поместил его в конец списка аргументов. Это сделало бы передачу аргументов и прочее через catch намного более естественной.
источник
args
иkwargs
через к ручке , а также. Таким образом вы можете вернуть sayegg
вместо жестко запрограммированного0
или исключения, как вы это делаете.handle
после**kwarg
и получилSyntaxError
. Вы имеете в виду разыменование какkwargs.get('handle',e)
?Ты можешь использовать
это просто пропустит нулевые элементы.
источник
Нет лучшего способа. Во многих случаях вы можете использовать избегание, как это делает Питер.
Другой вариант - не использовать понимания
Вам решать, будет ли это более громоздко или нет.
источник
Я думаю, что вспомогательная функция, предложенная тем, кто задает начальный вопрос, а также Брайаном Хедом, хороша и совсем не громоздка. Одна строка магического кода, которая выполняет всю работу, не всегда возможна, поэтому вспомогательная функция - идеальное решение, если кто-то хочет избежать
for
циклов. Однако я бы изменил его на этот:Выход будет такой
[(1/1, None), (1/3, None), (None, ZeroDivisionError), (1/3, None), (1/2, None)]
. С этим ответом вы полностью контролируете, чтобы продолжить как хотите.источник
Either
тип в некоторых языках функционального программирования (например, Scala), гдеEither
может содержать значение одного или другого типа, но не обоих одновременно. Единственная разница в том, что в этих языках идиоматично помещать ошибку слева, а значение - справа. Вот статья с дополнительной информацией .Я не видел ни одного ответа об этом. Но этот пример был бы одним из способов предотвратить возникновение исключения для известных случаев сбоя.
источник