プログラム周り

複数の値を比較するソート

pythonでソートをする際には、cmp(x,y)見たいなやり方をするのが一般的。 詳しくはこちらに書いてあるSorting Mini-HOWTO (和訳)。 classの中に__cmp__(self,other):と言う関数を作って、そのクラスから作ったインスタンスの配列に対して、hoge.sort()と言う風にすれば、その順序に、整列された配列が手に入る。

上のHowToに出ている例ではこんな感じ。

 class Spam:
     def __init__(self, spam, eggs):
         self.spam = spam
         self.eggs = eggs
     def __cmp__(self, other):
         return cmp(self.spam + self.eggs, other.spam + other.eggs)
     def __str__(self):
         return str(self.spam + self.eggs)
 
 a = [Spam(1, 4), Spam(9, 3), Spam(4, 6)]
 a.sort()
 for spam in a:
   print str(spam)

ところで、まず、身長で並べて、同じ身長だったら、体重でソートするとかしたい場合は?

っていう場合、どうすれば良いのだろうと思った。

たとえば、まず、身長の低い順に並べるけど、同じ高さなら、次は軽い順に並べるみたいなときはどうすればいいだろう。

どうやら、cmpは単純に、-1,0,1を返すので、0(等しい)場合は、次のcmpで、並べ替えれるみたいだ。

import random
class CmpTest:
    def __init__(self,tall,wei):
        self.tall=tall
        self.wei=wei
    def __cmp__(self,other):
        c=cmp(self.tall,other.tall)
        if c==0:
            c=cmp(self.wei,other.wei)
        return c
def main():
    k=[]
    for i in range(20):
        t=random.randint(1,3)
        w=random.randint(1,100)
        k.append(CmpTest(t,w))
    print "-"*20
    for p in k:
        print p.tall,p.wei
    k.sort()
    print "-"*20
    for p in k:
        print p.tall,p.wei
    print '-'*20
if __name__=='__main__':
    main()

で書いたプログラムがこれ。


前
2 21
1 46
2 42
3 69
3 29
3 47
1 17
1 13
1 92
3 40
2 61
2 83
3 12
3 52
2 71
3 2
1 22
2 44
2 74
2 9

後
1 13
1 17
1 22
1 46
1 92
2 9
2 21
2 42
2 44
2 61
2 71
2 74
2 83
3 2
3 12
3 29
3 40
3 47
3 52
3 69

肝は、

   def __cmp__(self,other):
       c=cmp(self.tall,other.tall)
       if c==0:
           c=cmp(self.wei,other.wei)
       return c

の部分、もし、同じ身長(c==0)なら、次は体重を比べろという風に書く。 そうすると、k.sort()でその様に並べてくれるようです。


トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2015-02-01 (日) 14:38:23 (3370d)