web-dev-qa-db-ja.com

Pythonラムダ内のキャッチブロックを試す

ラムダ関数内でtry catchブロックを使用することは可能ですか?特定の変数を整数に変換するにはラムダ関数が必要ですが、すべての値を整数に変換できるわけではありません。

37
scriptdiddy

いや。 A Python lambdaは単一の式のみです。名前付き関数を使用します。

型を変換するための汎用関数を作成すると便利です。

_def tryconvert(value, default, *types):
    for t in types:
        try:
            return t(value)
        except (ValueError, TypeError):
            continue
    return default
_

次に、ラムダを記述できます。

_lambda v: tryconvert(v, 0, int)
_

tryconvert()と書くこともできますreturns変換される値を受け取る関数。ラムダは必要ありません:

_def tryconvert(default, *types):
    def convert(value):
        for t in types:
            try:
                return t(value)
            except (ValueError, TypeError):
                continue
        return default
    # set name of conversion function to something more useful
    namext = ("_%s_" % default) + "_".join(t.__for t in types)
    if hasattr(convert, "__qualname__"): convert.__qual+= namext
    convert.__+= namext
    return convert
_

現在、tryconvert(0, int)は値を取り、それを整数に変換する関数を返し、これができない場合は_0_を返します。

59
kindall

必要に応じて、別のアプローチとしてtry:catchをラムダfnの外側に保持することもできます。

toint  = lambda x : int(x)
strval = ['3', '']

for s in strval:
    try:
        print 2 + toint(s)
    except ValueError:
        print 2

出力:

5
2
1
user

ラムダ式で例外を処理する一般的な方法はありませんが、少なくとも1種類の例外に対して制限された方法でそれを実現できます。式の一部からStopIterationをスローし、別の部分でキャッチすることができます。見る:

_from random import randrange

list((lambda:(yield from (randrange(0,2) or next(iter(())) for _ in (None,))))())
_

next(iter(()))StopIterationを発生させますが、_yield from_はそれをキャッチします。上記の式は、内部のランダム値に従って_[]_または_[1]_をランダムに返します(_0_は例外を発生させ、_1_は通常評価されます)。

詳細については http://baruchel.github.io/python/2018/06/20/python-exceptions-in-lambda/ を参照してください。

0
Thomas Baruchel