Pythonのlinecacheモジュールでテキストファイルの任意の行を読み込む方法
この記事では、Pythonの標準ライブラリであるlinecacheモジュールを使って、テキストファイルの内容を効率的に読み取る方法を解説します。行番号を指定して目的の行だけを素早く取得したい場面で役立つテクニックです。
linecacheモジュールとは
linecacheモジュールは、ファイルの内容を行単位に分割してメモリ上にキャッシュする仕組みを実装しています。キャッシュされた各行にはリストと同じようにインデックスでアクセスできるため、目的の行を探すために何度もファイルを読み込み直して解析する無駄な処理が不要になり、時間を大幅に節約できます。
特に、同じファイルから複数の行を繰り返し参照するようなケースでは、linecacheモジュールは非常に有効です。
テストデータの準備
まず、動作確認用のサンプルテキストを用意します。ここでは例として一般的なダミーテキスト「Lorem ipsum」を使用します。実際の開発では、任意のテキストファイルを用意して問題ありません。
Lorem ipsum dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.
Id porro facete cum. No est veritus detraxit facilisis, sit ea clita decore essent. Ut eam labores fuisset menandri, ex sit brute viderer eleifend, altera argumentum vel ex. Duo at zril sensibus, eu vim ullum assentior, quando possit at his.
Te nam tempor posidonium scripserit, eam mundi reprimique dissentias ne. Vim te soleat offendit democritum. Nam an diam elaboraret, quaeque dissentias an has. Autem legendos dignissim ad vis, sea ex amet petentium reprehendunt, inermis constituam philosophia ne mel. Esse noster lobortis usu ne.
Nec reque postea urbanitas ut, mea in nulla invidunt ocurreret. Ei duo iuvaret numquam. Ferri nemore audire te est, mel et detracto noluisse. Nec eu habeo justo, id pro posse apeirian volutpat. Mea sonet quaestio ne.
Atqui quaeque alienum te vim. Graeco aliquip liberavisse pro ut. Te similique reformidans usu, te mundi aliquando ius. Meis scripta minimum quo no, meis prima fabellas eu eam, laoreet delicata forensibus ut vim. Et quo vocibus mediocritatem, atqui summo an eam.
ステップ1:一時ファイルを作成・削除する関数を用意する
最初に、テスト用の一時ファイルを作成し、使用後に削除するための関数を定義します。tempfileモジュールのmkstemp()やmkdtemp()を使うと、一時ファイルや一時ディレクトリを安全かつ簡単に生成できます。
import os
import tempfile
text = """
Lorem ipsum dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.
Id porro facete cum. No est veritus detraxit facilisis, sit ea clita decore essent. Ut eam labores fuisset menandri, ex sit brute viderer eleifend, altera argumentum vel ex. Duo at zril sensibus, eu vim ullum assentior, quando possit at his.
Te nam tempor posidonium scripserit, eam mundi reprimique dissentias ne. Vim te soleat offendit democritum. Nam an diam elaboraret, quaeque dissentias an has. Autem legendos dignissim ad vis, sea ex amet petentium reprehendunt, inermis constituam philosophia ne mel. Esse noster lobortis usu ne.
Nec reque postea urbanitas ut, mea in nulla invidunt ocurreret. Ei duo iuvaret numquam. Ferri nemore audire te est, mel et detracto noluisse. Nec eu habeo justo, id pro posse apeirian volutpat. Mea sonet quaestio ne.
Atqui quaeque alienum te vim. Graeco aliquip liberavisse pro ut. Te similique reformidans usu, te mundi aliquando ius. Meis scripta minimum quo no, meis prima fabellas eu eam, laoreet delicata forensibus ut vim. Et quo vocibus mediocritatem, atqui summo an eam.
"""
def make_tempfile():
"""
関数:一時ファイルを作成する。
mkstemp()やmkdtemp()で一時ファイル・一時ディレクトリを生成できる。
引数:なし
戻り値:一時ファイルのパス。
"""
fd, temp_file = tempfile.mkstemp()
os.close(fd)
with open(temp_file, 'wt') as f:
f.write(text)
return temp_file
def cleanup(temp_file):
os.unlink(temp_file)ステップ2:linecacheで特定の行を読み込む
続いて、linecacheを使って特定の行を取得します。ここで重要なポイントがあります。通常のリストはインデックスが0から始まりますが、linecacheで読み込むファイルの行番号は1から始まるという点です。この違いは必ず覚えておきましょう。
import os
import tempfile
import linecache
text = """
Lorem ipsum dolor sit amet, causae apeirian ea his, duo cu congue prodesset. Ut epicuri invenire duo, novum ridens eu has, in natum meliore noluisse sea. Has ei stet explicari. No nam eirmod deterruisset, nusquam electram rationibus ad sea, interesset delicatissimi et sit. Purto molestiae cu eum, in per hinc periculis intellegam.
Id porro facete cum. No est veritus detraxit facilisis, sit ea clita decore essent. Ut eam labores fuisset menandri, ex sit brute viderer eleifend, altera argumentum vel ex. Duo at zril sensibus, eu vim ullum assentior, quando possit at his.
Te nam tempor posidonium scripserit, eam mundi reprimique dissentias ne. Vim te soleat offendit democritum. Nam an diam elaboraret, quaeque dissentias an has. Autem legendos dignissim ad vis, sea ex amet petentium reprehendunt, inermis constituam philosophia ne mel. Esse noster lobortis usu ne.
Nec reque postea urbanitas ut, mea in nulla invidunt ocurreret. Ei duo iuvaret numquam. Ferri nemore audire te est, mel et detracto noluisse. Nec eu habeo justo, id pro posse apeirian volutpat. Mea sonet quaestio ne.
Atqui quaeque alienum te vim. Graeco aliquip liberavisse pro ut. Te similique reformidans usu, te mundi aliquando ius. Meis scripta minimum quo no, meis prima fabellas eu eam, laoreet delicata forensibus ut vim. Et quo vocibus mediocritatem, atqui summo an eam.
"""
def make_tempfile():
"""
関数:一時ファイルを作成する。
mkstemp()やmkdtemp()で一時ファイル・一時ディレクトリを生成できる。
引数:なし
戻り値:一時ファイルのパス。
"""
directory = os.getcwd()
fd, temp_file = tempfile.mkstemp(dir=directory)
os.close(fd)
with open(temp_file, 'wt') as f:
f.write(text)
return temp_file
def cleanup(temp_file):
os.unlink(temp_file)
# ipsumデータを書き込んだファイルを作成
filename = make_tempfile()
print(f"出力 \n {filename}")
split_line = '\n'
# 元のテキストから直接行を取り出す
print(f"*** 元のテキストから直接表示した5行目 \n {text.split(split_line)[4]}")
# キャッシュから同じ行を取り出す
print(f"\n *** linecacheのキャッシュから表示した5行目 \n {linecache.getline(filename, 5)}")
# unlink()で一時ファイルを削除
cleanup(filename)実行結果
C:\Users\sasan\PycharmProjects\blog\TutorialPoints\Updated_Code\tmpazax_yne *** 元のテキストから直接表示した5行目 Id porro facete cum. No est veritus detraxit facilisis, sit ea clita decore essent. Ut eam labores fuisset menandri, ex sit brute viderer eleifend, altera argumentum vel ex. Duo at zril sensibus, eu vim ullum assentior, quando possit at his. *** linecacheのキャッシュから表示した5行目 Id porro facete cum. No est veritus detraxit facilisis, sit ea clita decore essent. Ut eam labores fuisset menandri, ex sit brute viderer eleifend, altera argumentum vel ex. Duo at zril sensibus, eu vim ullum assentior, quando possit at his.
元のテキストから直接取り出した行と、linecache経由で取得した行が一致していることが確認できました。
ステップ3:改行文字の扱いに注意する
linecacheは行末の改行文字も含めて値を返します。そのため、対象の行が空行だった場合、戻り値は改行文字のみになります。以下のコードで実際に確認してみましょう。
import linecache
# ipsumデータを書き込んだファイルを作成
filename = make_tempfile()
print(f"出力 \n {filename}")
# 空行には改行文字のみが含まれる
print(f"\n *** テキストの行数は13行です。")
print(" \n *** linecacheで最終行(空行なので改行のみのはず)を表示 \n {!r}".format(linecache.getline(filename, 8)))
cleanup(filename)実行結果
C:\Users\sasan\PycharmProjects\blog\TutorialPoints\Updated_Code\tmp352zirvn *** テキストの行数は13行です。 *** linecacheで最終行(空行なので改行のみのはず)を表示 '\n'
空行に対しては改行文字('\n')だけが返されていることが分かります。
まとめ
アプリケーションがファイルへのランダムアクセスを必要とする場合、linecacheを使えば行番号を指定して手軽に目的の行を読み出せます。一方で、ファイルの内容はすべてキャッシュとしてメモリ上に保持されるため、大きなファイルを扱う際にはメモリ消費量に注意が必要です。
-
PythonでPDFファイルをExcelファイルに変換する方法を解説
Pythonには、さまざまな処理に対応できる豊富なライブラリが用意されています。本記事では、その中でもPDFファイルをExcelファイルに変換する方法について詳しく解説します。PythonでPDFをCSV形式に変換できるパッケージは複数存在しますが、ここではTabula-pyモジュールを使用します。Tabula-pyの主要部分はJavaで書かれており、PDFドキュメントを読み込み、PythonのDataFrameとして取得したり、JSONオブジェクトに変換したりすることができます。事前準備:JavaのインストールTabula-pyを使用する前に、システムにJavaが事前にインストールされている
-
PythonでPowerPointファイルを自動作成する方法!python-pptxの基本を徹底解説
はじめに誰もが一度はPowerPointのプレゼンテーション資料を作成した経験があるのではないでしょうか。多くの場合、Microsoft PowerPointやGoogleスライドといったGUIツールを使うことが多いでしょう。しかし、ライセンスを持っていなかったり、インターネット環境にアクセスできなかったりすることもあります。あるいは、「プログラマーらしく」コードで自動生成したいと考える方もいるはずです。ご安心ください。そんなときこそPythonの出番です!この記事では、Pythonを使ってPowerPointファイルを作成し、コンテンツを追加する方法を解説します。それでは早速始めましょう!準