collections.defaultdict
で使用するために、list.sort
にkey
引数に類似したカスタムキー関数を定義するための良い方法は何ですか?カスタムキー機能は
ここでは例のユースケースです:
import collections
class Path(object):
def __init__(self, start, end, *other_features):
self._first = start
self._last = end
self._rest = other_features
def startpoint(self):
return self._first
def endpoint(self):
return self._last
# Maybe it has __eq__ and __hash__, maybe not
paths = [... a list of Path objects ...]
by_endpoint = collections.defaultdict(list)
for p in people:
by_last_name[p.endpoint()].append(p)
# do stuff that depends on lumping paths with the same endpoint together
私が望むことはlist.sort
からkey
引数に似key
関数としてPath.endpoint
使用するby_endpoint
を指示する方法であり、このキー定義を配置する必要はありませんPath
クラス自体に(__eq__
と__hash__
を使用して)、「開始点による一括処理」も同様に賢明です。
from collections import defaultdict
class defaultkeydict(defaultdict):
def __init__(self, default_factory, key=lambda x: x, *args, **kwargs):
defaultdict.__init__(self, default_factory, *args, **kwargs)
self.key_func = key
def __getitem__(self, key):
return defaultdict.__getitem__(self, self.get_key(key))
def __setitem__(self, key, value):
defaultdict.__setitem__(self, self.get_key(key), value)
def get_key(self, key):
try:
return self.key_func(key)
except Exception:
return key
注意キー機能を実行できない場合は、バック渡されたキーに該当するロジック:多分このような
これは 'defaultdict'とは何かを持っていますか?オブジェクト自身のデフォルトの等価性やハッシュ規則ではなく、オブジェクトの属性に基づいてオブジェクトをハッシュすることができるように思えますか?つまり、 'by_last_name [p]'と呼んで、 'p.last_name()'の呼び出し結果に基づいてシームレスにハッシュして比較することができればいいでしょうか?あるいは単に 'p.last_name()'を呼び出してそれをキーとして保存し、 'p'をキーとして保存しないでください。 – ShadowRanger
しかし、姓**は**人の定義の一部です。人のグループは、姓の人のハッシュになる可能性がありますが、それは人ではありません。 – kabanus
@ShadowRanger 'defaultdict'に依存しないアプローチがあるかもしれませんが、私が扱っている具体的なケースを提供しようとしました。' defaultdict'をクラスのインスタンスにサブセットでそれらのプロパティは、このフィーチャをクラス自体に組み込むことなく使用できます。 – Dave