2018年02月27日

言語処理100本ノックでPython入門 #18 - リストのソート

   このエントリーをはてなブックマークに追加 Clip to Evernote
言語処理100本ノック 2015の問題18に挑戦です。

■ 問題

hightemp.txtは,日本の最高気温の記録を「都道府県」「地点」「℃」「日」のタブ区切り形式で格納したファイルである.以下の処理を行うプログラムを作成し,hightemp.txtを入力ファイルとして実行せよ.さらに,同様の処理をUNIXコマンドでも実行し,プログラムの実行結果を確認せよ.

18. 各行を3コラム目の数値の降順にソート
各行を3コラム目の数値の逆順で整列せよ(注意: 各行の内容は変更せずに並び替えよ).確認にはsortコマンドを用いよ(この問題はコマンドで実行した時の結果と合わなくてもよい).

■ Pythonのコード
def sortBytemp(filename):
    with open(filename, 'r', encoding='utf8') as fin:
        lines = fin.readlines()
        #lines.sort(key=lambda x: float(x.split()[2]))
        #return lines
        return sorted(lines, key=lambda x: float(x.split()[2]))

def main(): lines = sortBytemp('hightemp.txt') for line in lines: print(line.rstrip())
if __name__ == '__main__': main()

■ リストの並び替え

いっぺんにメモリに読み込んでそれを並びかえることとします。 リストにsortメソッドが用意されています。調べてみると引数keyで比較キーを指定することができるみたいです。
lambdaキーワードを使って、以下のように書いてみたら、意図通りに並び替えてくれました。
lines.sort(key=lambda x: float(x.split()[2]))

C#風に書くと、
lines.OrderBy(s => double.Parse(s.split('\t')[2]));
みたいな感じですかね。

でも、このsortはリストそのものを並び替えてしまうんですね。
return lines.sort(key=lambda x: float(x.split()[2]))
って書いて、結果が表示されないので、あれっってなりました。

もし、元のリストの並びを保持したい場合には、
return sorted(lines, key=lambda x: float(x.split()[2]))
って書けば、新たなソート済みリストを生成してくれるみたいです。

■ 結果
千葉県	茂原	39.9	2013-08-11
埼玉県	鳩山	39.9	1997-07-05
大阪府	豊中	39.9	1994-08-08
山梨県	大月	39.9	1990-07-19
山形県	鶴岡	39.9	1978-08-03
愛知県	名古屋	39.9	1942-08-02
岐阜県	美濃	40	2007-08-16
群馬県	前橋	40	2001-07-24
山形県	酒田	40.1	1978-08-03
千葉県	牛久	40.2	2004-07-20
静岡県	佐久間	40.2	2001-07-24
愛媛県	宇和島	40.2	1927-07-22
群馬県	館林	40.3	2007-08-16
群馬県	上里見	40.3	1998-07-04
愛知県	愛西	40.3	1994-08-05
埼玉県	越谷	40.4	2007-08-16
山梨県	勝沼	40.5	2013-08-10
和歌山県	かつらぎ	40.6	1994-08-08
静岡県	天竜	40.6	1994-08-04
山梨県	甲府	40.7	2013-08-10
山形県	山形	40.8	1933-07-25
埼玉県	熊谷	40.9	2007-08-16
岐阜県	多治見	40.9	2007-08-16
高知県	江川崎	41	2013-08-12