5

次のリスト内包表記を使用しています。

resources = [obj.get("file") for obj in iterator if obj.get("file") != None]

if ステートメントでチェックされたときの値を「キャッシュ」して、戻りリストを生成するときに obj を再度obj.get("file")呼び出す必要がないようにする方法はありますか?get

4

5 に答える 5

10
resources = filter(None, (obj.get("file") for obj in iterator))

独自の評価関数を提供する方法については、 filterのドキュメントを参照してください。None(上記のように) 関数を渡すと、true でないすべての値が除外されます。

obj.get() が奇妙なメソッドを持つオブジェクトを返す場合、元のコードとまったく同じ結果を得るため__nonzero__に渡す必要があります。lambda obj: obj != None

于 2009-06-09T19:01:36.947 に答える
5

使用する代わりにリスト/イテレータの内包表記を使用したい場合は、次のようにfilter単純に使用できます。

resources = [file_obj
             for file_obj in (obj.get("file") for obj in iterator)
             if file_obj is not None]
于 2009-06-09T20:12:22.543 に答える
1

値を保持するための一時的なdictを作成します。次に、このdictをキャッシュとして使用する関数を作成し、次のようにリスト内包表記でその関数を使用します。

obj_cache = {}

def cache_get (target, key):
    if (target, key) not in obj_cache: obj_cache[(target, key)] = target.get(key)
    return obj_cache[(target, key)]

resources = [cache_get(obj, "file") for obj in iterator if cache_get(obj, "file") != None]

また、おそらくこれはすでに知っているでしょう(もしそうなら、この答えは無視してください)が、obj.get( "file")がデータベース呼び出しを行ったり、ファイルを開いたり、ネットワーク経由でリクエストを行ったり、その他の可能性がある場合を除きます。コストにO(n)を追加するだけなので、コストが高く、反復ごとに1回ではなく2回呼び出すことはおそらく無害です。

于 2009-06-09T19:20:55.817 に答える
1

次のようなことを試してください:

resources = filter( lambda x: x is not None, [obj.get("file") for ob jin iterator])
于 2009-06-09T19:02:58.097 に答える