テキストファイルの読み込み

ファイルの読み込み方法はいくつかありますが、まずは1行ずつ読み込み、すぐに処理する方法を覚えてみましょう。今回読み込むファイルはdata.txtというテキストファイルで、中には以下のように身長と体重とデータが入っているとします。

ファイルを開くにはopen関数を使い、for文で1行毎に処理します。

open関数

ファイル名は文字列を直接入力、もしくは文字列の変数で与えます。開き方は、ファイルの読み取りでは”r”を、書き込みでは”w”または”a”を指定します。”w”では既存のファイルがある場合は上書きを、”a”では末尾に追加します。開き方の指定が場合は”r”と同じ読み取りになります。

open関数で開いたファイルは1行ずつfor文の変数に読み込まれ、最終行まで読み込み終わるとfor文が終了します。以下の例は、ファイルを1行ずつ読み込んで、読み込んだ内容をprint関数で出力しています。全て読み終わると、Finish!を出力しています。

テキストファイルの処理

ファイルからの読み込みは、一行まるまる文字列として扱われます。先ほどのファイルの1行目は列のタイトルを表すコメント、2行目以降にデータがスペースで区切られた2列になって入っていますので、これらを処理し、列ごとの平均値を計算してみましょう。まずは一行目のコメントを無視するようにします。

for文でline変数に一行ずつ文字列を扱うにあたり、文頭に#がある場合、何もしないということを実現するためには、if 文を使えば次のように出来ます。

上の書き方でも問題はないのですが、データの処理(ここではprint(line))が2回インデントされたところになり、さらに中でif文やfor文を書くと、どんどんインデントが深くなってしまいます。そこで、continueという機能をつかうと、現在のループの残りの処理を飛ばして、次のループに移るという動作が行えるため、データ処理部のインデントを深くすることなく次のように書くことも出来ます。

line文字列の1文字目([0]で指定している文字)が#の場合、continueにより次のループに移り、結果として次の行が読み込まれます。

もしくは、コメントが1行目のみということに着目すれば、行数をカウントするための変数を用意し、1行目だけは無視するというやり方もあります。

今回の例ではどの記述の仕方でも問題ないと思いますが、3つ目のものだとコメントが所々挟まれるようなデータファイルには対応しづらいですね。好みとデータファイルの形式で適宜使い分けるといいと思います。

では次に、printの代わりに1行を文字列を2つの数値にし、平均を出すために身長はheight変数に、体重はweight変数に加算していきましょう。heightとweightはfor文内で定義すると文字列の分割と、数値への変換は「データを処理しよう」で説明したsplitfloatを使います。

さらに、データの数をカウントし、合計値をデータ数で割れば平均値になりますね。

実行結果

テキストファイルに書き出し

最後に、データを処理した結果をファイルに書き込みましょう。書き込みをするためにも、ファイルを開く(作る)必要があります。ファイルを開くには、読み込みと同じようにopen関数を使いますが、今回はfor文には組み込みません。ファイルを開いたという状態を変数に保存しておき、writelinesメソッドから書き込みを以下のように行います。

書き込む内容は文字列でなくてはなりません。また、ファイルを開いた状態の変数を作った場合、close()メソッドで閉じる癖をつけましょう。作成したファイルがプログラムで開かれたままの場合、他のプログラムで開けなかったり、エクスプローラからファイル名の変更や移動、削除が出来ない場合があります。

このファイルの書き込みを先ほどの平均化プログラムに組み込むと以下のようになります。

writeline()の中は文字列でなくてはなりません。str()で数値を文字列に変換し、+演算子で文字列を繋いでいます。最後の”\n”は改行記号です。

ファイルの入出力とデータ処理について、最低限覚えておけば自分なりにコードが書けるというものをお伝えしました。これだけでも簡単な処理は出来ると思いますが、便利な機能を覚えることでより複雑な処理を、効率的にプログラミングをすることが出来ます。