テキストの設定ファイルなどで、最後の行を改行コードで終わらすべきか、改行コード無しで終わらすべきかで迷ったことはありませんか?
仕事で使っているアプリケーションの中には、読み込むテキストデータの最後の行に改行を入れてはダメなものがいくつもありました。
その作りはどうなのかと思いますが、このアプリケーション、動作の結果から推測すると最後の改行コードの後、空文字列のデータ行があるように処理をしているように見えました。
Pythonでプログラムを作っているとき、ふと「Pythonで行を読み込んだときはどうなる?」か気になりましたので試してみました。
改行コードで終わっているテキストと終わっていないテキストを読み込む
実際に改行コードで終わっているテキストと終わっていないテキストをPythonで読み込んでみましょう。
最初に読み込むテキストを用意します。str1は改行コード(LF)で終わっている文字列、str2は終わっていない文字列です。これをファイルに書き込みます。
>>> str1 = 'First\nSecond\n' >>> str2 = 'First\nSecond' >>> open('nl_included', 'wt', newline='').write(str1) 13 >>> open('nl_included', 'wt', newline='').write(str2) 12
これをテキストエディタで見ると次のようになります。カーソルがあるところがファイルの末尾です。


さて、これを読み込むとどうなるか見てみましょう。
まずは、改行コードで終わっているファイルです。Pythonに改行コードをいじってほしくないので、open関数に「newline=''」を指定しています。
>>> f = open('nl_included', newline='') >>> included = f.readlines() >>> included ['First\n', 'Second\n']
readlines()は1行ずつ読み出して、1行分の文字列を要素に持つリストを返します。返されたリストを見てみると、2行分の要素があります。
期待していた通りです。最後の改行コードの後に余計なものは付いていません。
改行コードで終わっていないファイルも読み込んでみましょう。
>>> f = open('nl_not_included', newline='') >>> not_included = f.readlines() >>> not_included ['First\n', 'Second']
こちらも予想通りですね。最後の行は改行コードがついていません。
末尾の改行コードを削除する
行末の改行コードを削除するにはrstrip()を使うといいでしょう。
>>> [i.rstrip('\n') for i in included] ['First', 'Second'] >>> [i.rstrip('\n') for i in not_included] ['First', 'Second']
ただし、この記事の例では読み込むときに「newline=''」を指定しているので、改行コードがLFファイルは上記のように末尾の'\n'を削除すれば良いですが、改行コードがCRLFのときには行末に'\r\n'が付くのでうまく行きません。
一般的にはopen関数のnewline引数は省略(newline引数のデフォルトはNone)するか、または明示的に「newline=None」を指定するのが良いでしょう。
まとめ
これらの結果から、Pythonでテキストを読み込む場合は何も懸念する必要はありませね。
タイトルの問いに対しては、Pythonではどちらの場合でもうまく処理できますので、こだわる必要はありませんが、ファイルへ書き出すプログラムでは、「すべての行を同じように出力する」のが良いでしょう。つまりすべての行に改行コードを付けると言うことです。
遠い昔なのでうる覚えですが、「プログラミング言語C」を読んだときに、「最後を改行コードで終わらせるのは出力するプログラムの責任」というようことが書いてあったと記憶しています。
そしてwcコマンドの骨子のCプログラム例があって、このプログラムは最後が改行コードで終わってないと、正しく行数をカウントできなかったと思います。
$ wc -l nl_included 2 nl_included $ wc -l nl_not_included 1 nl_not_included
おっと、本物のwcコマンドは大丈夫かと思いましたが、Macのwcコマンドでも改行コードで終わってないと行数としてカウントしませんね。
やっぱり最後は改行コードで終わりましょう。