Pythonでファイルを1行ずつ読み込み|1行ずつ読み込み

python_read_the_file_line_by_line Python
python_read_the_file_line_by_line
この記事は約7分で読めます。

はじめに

どの言語でもファイルを1行ずつ読み込み、処理させることは多いかと思います。

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

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

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

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

例えば、PythonでCSVファイルを読み込み、処理したいときはcsvモジュールのDictReader()を使いましたが、単純にテキストファイルを1行ずつ読み込みする場合は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要素ずつ、つまり1行ずつ処理する形になります(改行が入っていますが)。

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

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

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

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

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

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

# 出力結果


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

まとめ

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

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

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

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

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

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

コメント

タイトルとURLをコピーしました