0

私が理解していることから、Pythonラムダはステートメントではなく式のみを許可します。ラムダ式で使用len()していて、関数呼び出しの戻り値の長さを取得しようとしている場合があります。ただし、その関数呼び出しは を返す可能性がありNone、これは を壊しlen()ます。これを回避する優雅な方法はありますか?

例:

def foo(obj_list, field):
    return maxk(obj_list, key=lambda obj: len(nested_getattr(obj, field)))

上記のは、引数を受け入れるmaxk()バージョンです。私はPython 2.4を使用しています(現在はそれ以上のものを使用できません)ので、ここから入手したキー引数を取るカスタム実装があります(投稿#140122および#140143を参照)。 のように動作しますが、別の属性内にネストされた属性を取得できる別のユーティリティ関数です。それはhere から入手できます。max()keymax()nested_getattr()getattr()

サンプル関数 (これは、変数/名前を変更して使用している実際の関数です) が行うことは、オブジェクトのリスト ( obj_list) を調べて、値の長さを比較し、全体で最大fieldのリスト内のオブジェクトを返すことです。field

ただし、field各オブジェクトの で指定された属性が を返すNone場合、は .len()でチョークしTypeErrorます。インライン条件を使用してこれを回避できると思いますがnested_getattr()、チェックのために1回、戻り値が でない場合はおそらく2回、2回呼び出す必要がありNoneます。戻り値を変数にキャッシュし、それを条件付きで実行してから、何を返すかを決定したいと思います (または、ジェネレータ式で完全にスキップさせます)。

これを処理する良い方法は何ですか? 私は、この関数、、maxk()またはnested_getattr()(必要な場合) の他の実装を受け入れます。

4

4 に答える 4

5

Just define the function separately as a regular function and then pass it into the maxk:

def getLen(obj):
    val = nested_getattr(obj, field)
    if val is None:
        return 0
    else:
        return len(val)
return maxk(obj, key=getLen)

Lambdas are meant to be used when it is easier to write an inline single-expression function that it would be to write a separate function. If it becomes harder to think of how to write the lambda than to just write a normal function, just write a normal function. There's no point spending time how to fit it into a lambda, because the lambda doesn't gain you anything in that case.

Edit: Lambdas are bytecode-identical to non-lambda functions that do the same thing.

>>> f = lambda x: x**2
>>> def g(x):
...     return x**2
>>> import dis
>>> dis.dis(f)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (2)
              6 BINARY_POWER        
              7 RETURN_VALUE        
>>> dis.dis(g)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (2)
              6 BINARY_POWER        
              7 RETURN_VALUE     
于 2012-09-26T22:45:32.727 に答える
3

多分これ:

lambda val: len(val or [])
于 2012-09-26T22:54:55.913 に答える
2

nested_getattr()の 3 番目の引数と同じ意味で に3 番目の引数を追加できますgetattr()

len(nested_getattr(obj, field, ''))  

また、この特定のケース len(nested_getattr(obj, field) or ''))(@DSM が推奨) では、返される値がシーケンスとNone.

一般に、@BrenBarn によって提案されているような名前付き関数が望ましい場合があります。

于 2012-09-26T22:56:02.533 に答える
0
def foo(obj_list, field):
    return maxk(obj_list, key=lambda obj: len(nested_getattr(obj, field) or []))

現在、2.4 でテストすることはできませんが、これは 3.2 で動作します。

于 2012-09-26T22:53:28.407 に答える