私はPythonで各反復が例外をスローできるリスト内包表記を持っています。
たとえば、私が持っている場合:
eggs = (1,3,0,3,2)
[1/Egg for Egg in eggs]
3番目の要素でZeroDivisionError
例外を取得します。
この例外を処理し、リスト内包表記の実行を継続するにはどうすればよいですか?
私が考えることができる唯一の方法は、ヘルパー関数を使用することです:
def spam(Egg):
try:
return 1/Egg
except ZeroDivisionError:
# handle division by zero error
# leave empty for now
pass
しかし、これは少し面倒です。
Pythonでこれを行うより良い方法はありますか?
注:これは簡単な例です(上記の「for instance」を参照)。実際の例ではコンテキストが必要なため、考えました。 。ゼロ除算エラーを回避するのではなく、リスト内包の例外を処理することに興味があります。
Pythonには例外を無視できる(または例外の場合は代替値&cを返す)組み込み式がないため、文字通り、リスト内の例外を処理することはできませんリスト内包表記は他の式を含む式であるためです(つまり、noステートメントであり、ステートメントのみが例外をキャッチ/無視/処理できます)。
関数呼び出しは式であり、関数本体には必要なすべてのステートメントを含めることができるため、気づいたように、例外が発生しやすい部分式の評価を関数に委任することは、実行可能な1つの回避策です(実行可能な場合は、他の回答でも示唆されているように、例外を引き起こす可能性のある値をチェックします)。
「リスト内包の例外を処理する方法」という質問に対する正しい回答は、すべてこの真実のすべての一部を表現しています。 2)実際には、可能な場合はジョブを関数に委任するか、エラーが発生しやすい値を確認します。したがって、これが答えではないという繰り返しの主張には根拠がありません。
私はこの質問がかなり古いことを知っていますが、この種のことをより簡単にする一般的な関数を作成することもできます:
def catch(func, handle=lambda e : e, *args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
return handle(e)
次に、あなたの理解で:
eggs = (1,3,0,3,2)
[catch(lambda : 1/Egg) for Egg in eggs]
[1, 0, ('integer division or modulo by zero'), 0, 0]
もちろん、デフォルトのハンドル関数を好きなように作成できます(たとえば、デフォルトでは「なし」を返します)。
これがあなたやこの質問の今後の視聴者に役立つことを願っています!
注:python 3では、 'handle'引数キーワードのみを作成し、引数リストの最後に配置します。これにより、catchを介して実際に引数などを渡すことがより自然になります。 。
使用できます
[1/Egg for Egg in eggs if Egg != 0]
これは、ゼロの要素を単にスキップします。
いいえ、より良い方法はありません。多くの場合、Peterのように回避を使用できます
他のオプションは、内包表記を使用しないことです
eggs = (1,3,0,3,2)
result=[]
for Egg in eggs:
try:
result.append(Egg/0)
except ZeroDivisionError:
# handle division by zero error
# leave empty for now
pass
それがもっと面倒かどうかを決めるのはあなた次第
最初の質問をする人とブライアンヘッドも提案したように、ヘルパー関数は良いもので、まったく面倒ではないと思います。すべての作業を行う1行のマジックコードが常に可能であるとは限らないため、for
ループを避けたい場合、ヘルパー関数は完璧なソリューションです。ただし、これを次のように変更します。
_# A modified version of the helper function by the Question starter
def spam(Egg):
try:
return 1/Egg, None
except ZeroDivisionError as err:
# handle division by zero error
return None, err
_
出力はこの[(1/1, None), (1/3, None), (None, ZeroDivisionError), (1/3, None), (1/2, None)]
になります。この答えを使用すると、任意の方法で続行するために完全に制御できます。