Pythonの辞書に対称入力データのキャッシュのための適切なfrozensetのですか?

StackOverflow https://stackoverflow.com/questions/2572899

  •  24-09-2019
  •  | 
  •  

質問

タイトル多かれ少なかれ、すべてのことを言います:

Iは、例えば、二つの引数に対称的な入力を取る機能を有しています

のようなもの
def f(a1, a2):
    return heavy_stuff(abs(a1 - a2))
今、私はいくつかのキャッシュ方法を紹介したいと思います。それは正しいだろう/ニシキヘビ/合理的に効率的にこのような何かを:

cache = {}
def g(a1, a2):
    fs =frozenset((tuple(a1), tuple(a2)))
    if fs not in cache:
        cache[fs] = f(a1, a2)
    return cache[fs]

または一部のより良い方法があるでしょう?

編集: A1とA2は、numpyの配列の行であるかもしれません。それの理由はI各タプルでそれらをラップします。

役に立ちましたか?

解決

Pythonは常にあなたが関数に渡しているすべての引数を計算し、唯一それが関数を呼び出すん。言い換えれば、他のほとんどの言語と同様、Pythonはその評価に「熱心」である(主な例外今日はおそらくHaskellのですが、それはあなたを助けない; - )。

setdefaultので、キャッシングのための非常にの不適当なアプローチです!あなたがするたびに

cache.setdefault(akey, f(x, y))

あなたがしているの最初のの多分床にその計算結果を落とすのそしてを、そのすべての計算コストで、f(x, y)を呼び出します。これは、キャッシュが完全に無効になります。

次のように

むしろは、常にそれを実行します。

akey = whatever(x, y)
if akey not in cache:
    cache[akey] = f(x, y)
return cache[akey]

など - いくつかの他の可能なイディオムは、存在している場合は特に、例えばあなたはそのfNoneを返すことはありません知っています:

result = cache.get(akey)
if result is None:
    result = cache[akey] = f(x, y)
return result

キーの計算のための適切なwhateverあなたはそのfが対称である知っていることを考えると、何の二次の問題については、私はfrozensetはおそらくOKだと思います。ただし(xyのコンポーネントは、同等のほか、ハッシュ可能であれば - すなわち、それは複素数と動作しないでしょう)あなたが

検討する必要があります
ta1 = tuple(a1)
ta2 = tuple(a2)
if ta1 > ta2: key = ta1, ta2
else: key = ta2, ta1

相対的な性能は、ハッシュの対、a1a2の項目を比較したコストに依存します。違いとにかく、マイナーである可能性が高いです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top