home changes contents help options

121:配列やハッシュをソートする

Ruby recipe bookには配列やハッシュをソートとなっているが、ハッシュというのを使ったことが無いので、ここではリストについて述べる。 リストを並び替えるには、sort()を使う。 実際の並び替えは、もっと複雑なので、判定する関数を自分で定義して使うことになる。 ここで、関数cmp(x,y) はx < y の時に負、x > y の時に正、x==y の時に0 を返すPython の組み込み関数である。 多分、リストの項目二つずつと次々に渡っていっているのではないかと思うが、よく分らない。

 >>> d=['apple','orange','melon']
 >>> d.sort()
 >>> d
 ['apple', 'melon', 'orange']

 >>> def cmpf(x,y):
        return -cmp(x[1],y[1])
 >>> d=[('kokugo', 86), ('rika', 40), ('syakai', 75)]
 >>> d.sort(cmpf)
 >>> print d
 [('kokugo', 86), ('syakai', 75), ('rika', 40)]

逆順に並べるときは、

 >>> a=[5,2,3,1,4]
 >>> def reverse_numeric(x,y):
        return cmp(y,x)
 >>> a.sort(reverse_numeric)
 >>> a
 [5, 4, 3, 2, 1]

しかし、毎回関数を呼び出すのは時間がかかるので、 普通にソートしてリバースする ほうがいいらしい。

 >>> a=[5,2,3,1,4]
 >>> a.sort()
 >>> a
 [1, 2, 3, 4, 5]
 >>> a.reverse()
 >>> a
 [5, 4, 3, 2, 1]

多次元配列のソートは次のようにします。

2番目の項目で昇順にソート :

 >>> lst=[['apple',3800,27],['orange',250,50],['melon',5000,10],['orange',300,20],['orange',250,10]]
 >>> from operator import itemgetter
 >>> sorted(lst,key=itemgetter(1))
 [['orange', 250, 50], ['orange', 250, 10], ['orange', 300, 20], ['apple', 3800, 27], ['melon', 5000, 10]]

2番目の項目で降順にソート :

 >>> sorted(lst,key=itemgetter(1),reverse=True)
 [['melon', 5000, 10], ['apple', 3800, 27], ['orange', 300, 20], ['orange', 250, 50], ['orange', 250, 10]]

2番目の項目で昇順にソートしますが、値が同じなら3番目で並び替えます。何をしているのか分からないので誰か解説してください。

 >>> sorted(lst,key=lambda v: v[1:])
 [['orange', 250, 10], ['orange', 250, 50], ['orange', 300, 20], ['apple', 3800, 27], ['melon', 5000, 10]]

多次元配列はこちらが参考になります。

http://blog.livedoor.jp/yawamen/archives/51492356.html

http://d.hatena.ne.jp/yumimue/20071218/1197985024