LoginSignup
7
1

More than 5 years have passed since last update.

素人の言語処理100本ノック:18

Last updated at Posted at 2016-10-05

言語処理100本ノック 2015の挑戦記録です。環境はUbuntu 16.04 LTS + Python 3.5.2 :: Anaconda 4.1.1 (64-bit)です。過去のノックの一覧はこちらからどうぞ。

第2章: UNIXコマンドの基礎

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

18.各行を3コラム目の数値の降順にソート

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

出来上がったコード:

main.py
# coding: utf-8

fname = 'hightemp.txt'
lines = open(fname).readlines()
lines.sort(key=lambda line: float(line.split('\t')[2]), reverse=True)

for line in lines:
    print(line, end='')

実行結果:

端末
高知県   江川崎   41  2013-08-12
埼玉県   熊谷  40.9    2007-08-16
岐阜県   多治見   40.9    2007-08-16
山形県   山形  40.8    1933-07-25
山梨県   甲府  40.7    2013-08-10
和歌山県    かつらぎ    40.6    1994-08-08
静岡県   天竜  40.6    1994-08-04
山梨県   勝沼  40.5    2013-08-10
埼玉県   越谷  40.4    2007-08-16
群馬県   館林  40.3    2007-08-16
群馬県   上里見   40.3    1998-07-04
愛知県   愛西  40.3    1994-08-05
千葉県   牛久  40.2    2004-07-20
静岡県   佐久間   40.2    2001-07-24
愛媛県   宇和島   40.2    1927-07-22
山形県   酒田  40.1    1978-08-03
岐阜県   美濃  40  2007-08-16
群馬県   前橋  40  2001-07-24
千葉県   茂原  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

UNIXコマンド確認用のシェルスクリプト:

test.sh
#!/bin/sh

# 3カラム目を数値として逆順ソート
sort hightemp.txt --key=3,3 --numeric-sort --reverse > result_test.txt

# Pythonのプログラムで実行
python main.py > result.txt

# 結果の確認
diff --report-identical-files result.txt result_test.txt

結果の確認:

端末
segavvy@ubuntu:~/ドキュメント/言語処理100本ノック2015/18$ ./test.sh
10d9
< 群馬県 館林  40.3    2007-08-16
11a11
> 群馬県 館林  40.3    2007-08-16
17d16
< 岐阜県 美濃  40  2007-08-16
19,20c18
< 千葉県 茂原  39.9    2013-08-11
< 埼玉県 鳩山  39.9    1997-07-05
---
> 岐阜県 美濃  40  2007-08-16
21a20
> 千葉県 茂原  39.9    2013-08-11
23a23
> 埼玉県 鳩山  39.9    1997-07-05

diffで違いが検出されてしまいましたが、3カラム目の気温は同値があるので、その部分で違うのは仕方がないでしょう。

ラムダ式

今回初めてラムダ式を使ってみました。lambda line: float(line.split('\t')[2])の部分です。与えられた文字列lineに対して、¥t区切りで分割した3カラム目をfloatとして返す、という関数の代わりに使っています。ただ、少し分かりにくくなりますね。内包表記もそうですが、この辺は慣れもあるかとは思います。

ちなみにPythonのドキュメントの小さな関数とラムダ式の解説では、著者の方はラムダなしのスタイルが好みとのことでした。

ソートの型

ソートの時は対象データの型に注意が必要です。
今回の対象データでは、ラムダ式でfloatに変換し忘れたり、UNIXコマンドのsort--numeric-sortをつけ忘れても正しい結果になりますが、もし気温が5度の場所が混ざっていたりすると、気温が一番低いにも関わらず先頭に来てしまいます。
 
19本目のノックは以上です。誤りなどありましたら、ご指摘いただけますと幸いです。

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1