私は次のリストの内包表記を使用しています:キャッシュ値
resources = [obj.get("file") for obj in iterator if obj.get("file") != None]
はそれがないように、それはif文でチェックだときobj.get("file")
の値を「キャッシュ」する方法はあります返信リストを生成するときにobhに対してget
を再度呼び出す必要がありますか?
私は次のリストの内包表記を使用しています:キャッシュ値
resources = [obj.get("file") for obj in iterator if obj.get("file") != None]
はそれがないように、それはif文でチェックだときobj.get("file")
の値を「キャッシュ」する方法はあります返信リストを生成するときにobhに対してget
を再度呼び出す必要がありますか?
あなたの代わりにあなたは、単に使用することができますfilter
使用して一覧/イテレータの内包表記で滞在したい場合:
resources = [file_obj
for file_obj in (obj.get("file") for obj in iterator)
if file_obj is not None]
resources = filter(None, (obj.get("file") for obj in iterator))
独自の評価機能を提供する方法については、filterのドキュメントを参照してください。上記のように関数にNone
を渡すと、真ではないすべての値が除外されます。
obj.get()が奇妙な__nonzero__
メソッドを持つオブジェクトを返す場合、元のコードとまったく同じ結果を得るにはlambda obj: obj != None
を渡す必要があります。
「奇妙な__nonzero__持つオブジェクト」 - int型、またはstrのように。 –
はこのような何かを試してみてください:
resources = filter(lambda x: x is not None, [obj.get("file") for ob jin iterator])
フィルターにラムダ関数は必要ありません。 Noneを渡すことで、デフォルトで恒等関数になります(falseに評価されるオブジェクトは除外されます)。 http://docs.python.org/library/functions.html#filter – tgray
2番目の考えでは、イテラブルに他の「偽の」要素(0など)がある場合、ラムダが必要な場合があります。 – tgray
Hmm。もし私がそれを必要としなくても、私はラムダの証言を好きです。 – SingleNegationElimination
値を保持するために、一時的な辞書を作成します。その後、キャッシュとしてこの辞書を使用する関数を作成し、そのように、リスト内包でその機能を使用します。
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")がデータベース呼び出しを行ったり、ファイルを開いたり、ネットワークを介して要求したり、高価なものを実行したりしない限り、1回ではなく2回繰り返すことはおそらく無害です。あなたのコストにO(n)を加えるだけです。
ありがとう、これは私が探していた一般的な解決策です。 – Kai