比較関数を追加可能なcomparator
夕方にちょっと話にでてきたので想像で実装してみた。
class ExtensibleComparator(object): def __init__(self): self.ops = [] def __call__(self, x, y): for op in self.ops: n = op(x, y) if n == -1: return -1 elif n == 1: return 1 return 0 def add(self, op): self.ops.append(op) def compare_fuctory(key_fn): def _compare(x, y): xx, yy = key_fn(x), key_fn(y) if xx == yy: return 0 return 1 if xx > yy else -1 return _compare
使い方
こんな風に使う
from collections import namedtuple fact = namedtuple("F", "cost benefit") xs = [fact(4, 4), fact(5, 10), fact(10, 20), fact(5, 8), fact(10, 10)] ec = ExtensibleComparator() # costの順で並べる ec.add(compare_fuctory(lambda x : x.cost)) print sorted(xs, ec) # costが同じだったら、benefitの順で並べる ec.add(compare_fuctory(lambda x : x.benefit)) print sorted(xs, ec) ### print "--------" ec2 = ExtensibleComparator() # benefit/costの値で並べる ec2.add(compare_fuctory(lambda x : x.benefit / x.cost)) print sorted(xs, ec2) # 比率が同じだったら、benefitの大きいものから順に並べる。 ec2.add(compare_fuctory(lambda x : -x.benefit)) print sorted(xs, ec2)
結果
使った結果
[F(cost=4, benefit=4), F(cost=5, benefit=10), F(cost=5, benefit=8), F(cost=10, benefit=20), F(cost=10, benefit=10)] [F(cost=4, benefit=4), F(cost=5, benefit=8), F(cost=5, benefit=10), F(cost=10, benefit=10), F(cost=10, benefit=20)] -------- [F(cost=4, benefit=4), F(cost=5, benefit=8), F(cost=10, benefit=10), F(cost=5, benefit=10), F(cost=10, benefit=20)] [F(cost=10, benefit=10), F(cost=5, benefit=8), F(cost=4, benefit=4), F(cost=10, benefit=20), F(cost=5, benefit=10)]
たぶんこんな感じのものだと予想してる。