python_read_the_file_line_by_line

はじめに

どの言語でもファイルを一行ずつ読み込む処理は多いかと思います。

CSVファイルであったりテキストファイルであったり様々ですが、今回はテキストファイルについてアップしてみました。

CSVファイルの読み込みや書き込みについてもコンテンツをアップしていますので、少し下に貼り付けたリンクから辿って頂ければと思います。

あとは、日本語などの2バイト系文字列の場合、気を付けないと文字化けを起こしてしまうのでエンコーディングの設定も忘れないようにしましょう。

テキストファイルを一行ずつ読み込む

例えば、CSVファイルを読み込むときはcsvモジュールのDictReader()を使いましたが、単純にテキストファイルを一行ずつ読み込む場合はreadlines()を使用します。

CSVファイルの読み込みや書き込みが知りたい方はこちらをご参考にしてください。

以下、サンプルプログラムです。

# まずsample.txtを用意する
text_data = """
aaaaaaaaaaaaaaa
bbbbbbbbbbbbbbb
ccccccccccccccc
"""

# 一旦、書き込みます
with open('sample.txt', 'w') as f:
    f.write(text_data)

# ファイルの内容を一行ずつ読み込む
with open('sample.txt', 'r') as f:
    file_data = f.readlines()
    for line in file_data:
        print(line)

# 出力結果


aaaaaaaaaaaaaaa

bbbbbbbbbbbbbbb

ccccccccccccccc

ん~、余分な改行が入っていますね。

余分な改行を除去します。

# ファイルの内容を一行ずつ読み込む
with open('sample.txt', 'r') as f:
    file_data = f.readlines()
    for line in file_data:
        #print(line)
        print(line.rstrip())

# 出力結果

aaaaaaaaaaaaaaa
bbbbbbbbbbbbbbb
ccccccccccccccc

rstrip()によって行末の余分な改行を削除できました。

ただ、ファイルの先頭にある、改行だけの行(空行)も削除するには別途if文を使って処理します。

# ファイルの内容を一行ずつ読み込む
with open('sample.txt', 'r') as f:
    file_data = f.readlines()
    for line in file_data:
        clean_line = line.strip()
        if not clean_line:
            print('空行です。スキップします。')
            continue
        print(clean_line)

# 出力結果
空行です。スキップします。
aaaaaaaaaaaaaaa
bbbbbbbbbbbbbbb
ccccccccccccccc

これで綺麗に空行をスキップできましたね。

上記のfile_data[0]は改行だけが入っているのでstrip()で改行を除去しif文で判定させる、という流れです。

マッチすればcontinueすればいいだけですね。

日本語などの2バイト系文字列の場合

ただ、日本語などの2バイト系文字列の場合、このままだと文字化けしてしまいます。

日本語などを扱うときはwithステートメントの第三引数に文字コードを指定してあげます。

print('日本語などの2バイト系の場合はこちら。')

# sample_jp.txt を用意する
japanese_text = """
【1行目】日本語にはひらがな、カタカタ、漢字があり、
【2行目】外国人が日本語を勉強するときは非常に大変そうです。
【3行目】日本人に生まれてきてよかったと思う今日この頃。
"""

# utf-8として書き込む
with open('japanese.txt', 'w', encoding='utf-8') as f:
    f.write(japanese_text)

# utf-8として、1行ずつ読み込む
with open('japanese.txt', 'r', encoding='utf-8') as f:
    file_data = f.readlines()
    for line in file_data:
        print(line.rstrip())

# 出力結果
日本語などの2バイト系の場合はこちら。

【1行目】日本語にはひらがな、カタカタ、漢字があり、
【2行目】外国人が日本語を勉強するときは非常に大変そうです。
【3行目】日本人に生まれてきてよかったと思う今日この頃。

このとき、readlines()の戻り値を確認してみるとリストであり、中身は次のようになっています。

  # utf-8として、1行ずつ読み込む
with open('japanese.txt', 'r', encoding='utf-8') as f:
    file_data = f.readlines()
    print(type(file_data))
    print(file_data)
    for line in file_data:
        print(line.rstrip())

# 出力結果
<class 'list'>
['\n', '【1行目】日本語にはひらがな、カタカタ、漢字があり、\n', '【2行目】外国人が日本語を勉強するときは非常に大変そうです。\n', '【3行目】日本人に生まれてきてよかったと思う今日この頃。\n']

【1行目】日本語にはひらがな、カタカタ、漢字があり、
【2行目】外国人が日本語を勉強するときは非常に大変そうです。
【3行目】日本人に生まれてきてよかったと思う今日この頃。

リスト形式なのでfor文に渡したときに1要素ずつ、つまり一行ずつ処理する形になります(改行が入っていますが)。

行末にある改行を除去したいときは、rstrip()を使用します。

でも、今回のようにリストのfile_data[0]にある改行を除去したい場合はどうしたらいいかと言うと、上記でも説明しましたがstrip()で改行を除去した後、if文で空文字かどうかを判定させ空文字であればcontinueさせる、というやり方が自分的にはいいのかなと思いました。

read()を使ってファイルを読み込む場合

read()を使ってファイルの中身を読み込むと、ファイルの中身をひとつの文字列の値として処理します。

ですので、一行ずつ処理する形では不向きかと思いますが、
一文字ずつ処理するのであればループで回せば良いかなと。

# ファイル全体をひとつの文字列として読み込む
with open('japanese.txt', 'r', encoding='utf-8') as f:
    file_data = f.read()
    for line in file_data:
        print(line)

# 出力結果


【
1
行
目
】
日
本
語
に
は
ひ
ら
が
な
、

まとめ

ファイルの中身を読み込んで加工する処理はどの言語でも多いかと思いますが、安全に処理させようと思えば例外処理も細かく入れてあげる必要がありますね。

あるはずのファイルが存在しなかった場合でも例外処理を施しておけば安心ですし。

まぁ若干、面倒ではあるのですが。

普段からガリガリプログラムを書かないと、いざ使うときにすぐ頭に出てこないんですよね。。

色々忙しいんですが、もう少しプログラムに専念したいなぁ。

ご参考になれば幸いです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください