2016-11-30 6 views
0

collections.defaultdictで使用するために、list.sortkey引数に類似したカスタムキー関数を定義するための良い方法は何ですか?カスタムキー機能は

ここでは例のユースケースです:

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 

注意キー機能を実行できない場合は、バック渡されたキーに該当するロジック:多分このような

+0

これは 'defaultdict'とは何かを持っていますか?オブジェクト自身のデフォルトの等価性やハッシュ規則ではなく、オブジェクトの属性に基づいてオブジェクトをハッシュすることができるように思えますか?つまり、 'by_last_name [p]'と呼んで、 'p.last_name()'の呼び出し結果に基づいてシームレスにハッシュして比較することができればいいでしょうか?あるいは単に 'p.last_name()'を呼び出してそれをキーとして保存し、 'p'をキーとして保存しないでください。 – ShadowRanger

+0

しかし、姓**は**人の定義の一部です。人のグループは、姓の人のハッシュになる可能性がありますが、それは人ではありません。 – kabanus

+0

@ShadowRanger 'defaultdict'に依存しないアプローチがあるかもしれませんが、私が扱っている具体的なケースを提供しようとしました。' defaultdict'をクラスのインスタンスにサブセットでそれらのプロパティは、このフィーチャをクラス自体に組み込むことなく使用できます。 – Dave

答えて

0

何か。そうすれば、文字列やその他のキーを使って項目にアクセスすることができます。

今:

p = Path("Seattle", "Boston") 
d = defaultkeydict(list, key=lambda x: x.endpoint()) 
d[p].append(p) 
print(d)  # defaultdict(<type 'list'>, {'Boston': [<__main__.Path object at ...>]}) 
+0

これは、関数__key__をクラスに入れる必要があるため、役に立ちません。私はこれを避けようとしています。 – Dave

+0

含まれているオブジェクトではなくコンテナにロジックを書き込むように書き換えます。 – kindall

関連する問題