ファイルを1行ずつリストに読み込む方法は?


2027

Pythonでファイルのすべての行を読み取り、各行を要素としてリストに保存するにはどうすればよいですか?

ファイルを1行ずつ読み取り、リストの最後に各行を追加したいと思います。

回答:


2174
with open(filename) as f:
    content = f.readlines()
# you may also want to remove whitespace characters like `\n` at the end of each line
content = [x.strip() for x in content] 

206
使用しないでくださいfile.readlines()for-ループ、ファイルオブジェクト自体が十分である:lines = [line.rstrip('\n') for line in file]
JFS

88
ビッグデータを使用している場合readlines()MemoryErrorが発生する可能性があるため、あまり効率的ではありません。この場合for line in f:、各line変数を使用して作業するファイルを反復処理することをお勧めします。
DarkCygnus

7
ここで説明した手順を使用して、回答に示されているさまざまな方法のメモリプロファイルを確認しましたここの @DevShark 提案されているように、各行がファイルから読み取られて処理されると、メモリ使用量ははるかに良くなります。メモリが制約であるか、ファイルが大きい場合、コレクションオブジェクトのすべての行を保持することはお勧めできません。実行時間はどちらの方法でも同じです。
Tirtha R 2018

6
また、.rstrip()行末から空白を取り除く場合は、少し速く動作します。
Gringo Suave

Oneliner:with open(filename) as f: content = [i.strip() for i in f.readlines()]
Vishal Gupta

1002

入力と出力を参照してください。

with open('filename') as f:
    lines = f.readlines()

または改行文字を削除して:

with open('filename') as f:
    lines = [line.rstrip() for line in f]

12
f.read().splitlines()改行を削除するを使用してください
Mark

for line in open(filename)安全な2番目のバージョンはありますか?つまり、ファイルは自動的に閉じられますか?
becko 2016

2
ファイル全体を一度にメモリに読み込むのではなく、ファイルを1行ずつ読み込むのが最善です。これを行うと、大きな入力ファイルではうまく拡張できません。ロバートによる以下の回答を参照してください。
Brad Hein

1
lines = [x.rstrip('\n') for x in open('data\hsf.txt','r')]このように書き込んだ場合、読み取り後にファイルを閉じるにはどうすればよいですか?
Ramisa Anjum Aditi

2
はい、他の人がここで作成しているところまでopen、コンテキストマネージャーなしで使用することは「ベストプラクティス」ではありません(またはそれを閉じるための他の保証された方法)、これは実際にはそれらのケースの1つではありません-オブジェクトに参照がない場合リスト内包の処理が完了すると、ガベージコレクションされてファイルが閉じられます。
アーロンホール

579

これは必要以上に明白ですが、あなたが望むことをします。

with open("file.txt") as file_in:
    lines = []
    for line in file_in:
        lines.append(line)

18
ファイル全体をメモリにロードする必要がないため、この回答をお勧めします(この場合はarray、追加されますが、他の状況も考えられます)。確かに大きなファイルの場合、このアプローチは問題を軽減するかもしれません。
JohannesB

1
配列への追加が遅い。これが最善の解決策であるユースケースは考えられません。
エリアスストレー

@haccksは、ファイル全体をメモリにロードしないため、それともそれ以上ですか?
OrigamiEye

4
注:このソリューションは改行を取り除きません。
AMC

1
このソリューションは、ファイル全体をメモリにロードします。なぜ人々がそうではないと思うのか、私にはわかりません。
andrebrait

274

これにより、ファイルから行の「配列」が生成されます。

lines = tuple(open(filename, 'r'))

open反復可能なファイルを返します。ファイルを反復処理すると、そのファイルから行が取得されます。tupleイテレータを取得し、指定したイテレータからタプルインスタンスをインスタンス化できます。linesファイルの行から作成されたタプルです。


31
@MarshallFarrier lines = open(filename).read().split('\n')代わりに試してください。
Noctisスカイタワー2014

16
ファイルを閉じますか?
Vanuan

5
@Vanuan行の実行後にファイルへの参照が残っていないため、デストラクタ自動的にファイルを閉じる必要があります。
Noctisスカイタワー、2015年

30
@NoctisSkytower lines = open(filename).read().splitlines()少しすっきりしているので、DOSの行末もより適切に処理できると思います。
jaynp

8
@ mklement0 1000行のファイルを想定すると、a listはaよりも約13.22%多くのスペースを占めますtuple。結果はから来ていfrom sys import getsizeof as g; i = [None] * 1000; round((g(list(i)) / g(tuple(i)) - 1) * 100, 2)ます。a tupleを作成するlistと、作成するよりも約4.17%時間がかかります(標準偏差は0.16%)。結果はfrom timeit import timeit as t; round((t('tuple(i)', 'i = [None] * 1000') / t('list(i)', 'i = [None] * 1000') - 1) * 100, 2)30回実行した結果です。私のソリューションでは、可変性の必要性が不明な場合、速度よりもスペースを優先します。
Noctisスカイタワー2016年

194

\n含めたい場合:

with open(fname) as f:
    content = f.readlines()

\n含めたくない場合:

with open(fname) as f:
    content = f.read().splitlines()

168

Pythonのファイルオブジェクトメソッドによると、テキストファイルをに変換する最も簡単な方法listは次のとおりです。

with open('file.txt') as f:
    my_list = list(f)

テキストファイルの行を反復処理する必要があるだけの場合は、次を使用できます。

with open('file.txt') as f:
    for line in f:
       ...

古い答え:

withおよびの使用readlines()

with open('file.txt') as f:
    lines = f.readlines()

ファイルを閉じてもかまわない場合は、次の1行で機能します。

lines = open('file.txt').readlines()

伝統的な方法:

f = open('file.txt') # Open file on read mode
lines = f.read().split("\n") # Create a list containing all lines
f.close() # Close file

150

提案されているように、単に次のことを実行できます。

with open('/your/path/file') as f:
    my_lines = f.readlines()

このアプローチには2つの欠点があることに注意してください。

1)すべての行をメモリに保存します。一般的なケースでは、これは非常に悪い考えです。ファイルが非常に大きくなり、メモリ不足になる可能性があります。大きくなくても、単なるメモリの浪費です。

2)これは、あなたがそれらを読むときに、各行の処理を許可しません。したがって、この後に行を処理する場合、効率的ではありません(1つではなく2つのパスが必要です)。

一般的なケースのより良いアプローチは次のようになります:

with open('/your/path/file') as f:
    for line in f:
        process(line)

プロセス関数を好きなように定義する場所。例えば:

def process(line):
    if 'save the world' in line.lower():
         superman.save_the_world()

Supermanクラスの実装は演習として残しておきます)。

これはどのファイルサイズでも問題なく機能し、1パスでファイルを処理できます。これは通常、汎用パーサーが機能する方法です。


5
これはまさに私が必要としていたことでした-欠点を説明してくれてありがとう。Pythonの初心者として、ソリューションがソリューションである理由を理解するのは素晴らしいことです。乾杯!
Ephexx 2016年

5
コーリーについてもう少し考えてみてください。これらの行で何もせずに、コンピュータで各行を本当に読みたいと思いますか?確かに、常に何らかの方法でそれらを処理する必要があることに気付くでしょう。
DevShark 2016

5
あなたはいつも線で何かをする必要があります。行を印刷したり数えたりするのと同じくらい簡単です。プロセスにメモリ内の行を読み取らせることは意味がありませんが、それを使って何もしません。
DevShark

2
あなたはいつも彼らと何かをする必要があります。あなたがしようとしているポイントは、関数を1つずつではなく、一度にすべてに適用したいということです。それは確かに時々そうです。ただし、メモリの観点からは非効率的であり、フットプリントがRAMよりも大きい場合、ファイルを読み取ることができません。これが、一般的な汎用パーサーが私が説明した方法で動作する理由です。
DevShark 2017年

2
正しい@PierreOcinom。ファイルが読み取り専用モードで開かれている場合、上記のコードで元のファイルを変更することはできません。読み取りと書き込みの両方でファイルを開くには、次を使用しますopen('file_path', 'r+')
DevShark

65

リストへのデータ

次の行のようなデータを含むテキストファイルがあるとします。

テキストファイルの内容:

line 1
line 2
line 3
  • 同じディレクトリでcmdを開きます(マウスを右クリックして、cmdまたはPowerShellを選択します)
  • 実行pythonし、インタープリターで書き込みます。

Pythonスクリプト:

>>> with open("myfile.txt", encoding="utf-8") as file:
...     x = [l.rstrip("\n") for l in file]
>>> x
['line 1','line 2','line 3']

追加の使用:

x = []
with open("myfile.txt") as file:
    for l in file:
        x.append(l.strip())

または:

>>> x = open("myfile.txt").read().splitlines()
>>> x
['line 1', 'line 2', 'line 3']

または:

>>> x = open("myfile.txt").readlines()
>>> x
['linea 1\n', 'line 2\n', 'line 3\n']

または:

def print_output(lines_in_textfile):
    print("lines_in_textfile =", lines_in_textfile)

y = [x.rstrip() for x in open("001.txt")]
print_output(y)

with open('001.txt', 'r', encoding='utf-8') as file:
    file = file.read().splitlines()
    print_output(file)

with open('001.txt', 'r', encoding='utf-8') as file:
    file = [x.rstrip("\n") for x in file]
    print_output(file)

出力:

lines_in_textfile = ['line 1', 'line 2', 'line 3']
lines_in_textfile = ['line 1', 'line 2', 'line 3']
lines_in_textfile = ['line 1', 'line 2', 'line 3']

1
read().splitlines()Pythonによって提供されます。それreadlines()は単純です(無駄が少ないため、おそらくより高速です)。
エリックOレビゴット2018年

1
示された例から@EricOLebigot、それはのように見えるread().splitlines()readlines()同じ出力を生成しません。それらは同等ですか?
craq

1
readlineのみを使用する場合は、stripメソッドを使用してテキストの\ nを取り除く必要があるため、リスト内包表記を使用して最後の例を変更し、両方のケースで同じ出力を取得しました。したがって、read()。readlines()を使用すると、改行文字のない、行を含む「クリーン」なアイテムが作成されます。それ以外の場合は、上記のコードに表示されていることを行う必要があります。
Giovanni G. PY

1
確かに。上記のすべてのコードでことに注意しstrip()なければならないrstrip("\n")か、線の周りにスペースが削除されます。また、readlines()リスト内包で実行しても意味がありません。行の中間リストを作成することで時間とメモリを無駄にしないため、単にファイルを反復する方が優れています。
エリックOレビゴ

1
@EricOLebigot完了、ありがとう。
Giovanni G. PY

43

ファイルをリストに読み込むには、次の3つのことを行う必要があります。

  • ファイルを開く
  • ファイルを読む
  • 内容をリストとして保存

さいわい、Pythonではこれらのことを非常に簡単に実行できるので、ファイルをリストに読み込む最短の方法は次のとおりです。

lst = list(open(filename))

ただし、もう少し説明を加えます。

ファイルを開く

特定のファイルを開きたいのに、ファイルハンドル(またはファイルのようなハンドル)を直接処理しないと仮定します。Pythonでファイルを開くために最も一般的に使用される関数はでopen、Python 2.7では1つの必須の引数と2つのオプションの引数を取ります。

  • ファイル名
  • モード
  • バッファリング(この回答ではこの引数を無視します)

ファイル名は、ファイルへのパスを表す文字列である必要があります。例えば:

open('afile')   # opens the file named afile in the current working directory
open('adir/afile')            # relative path (relative to the current working directory)
open('C:/users/aname/afile')  # absolute path (windows)
open('/usr/local/afile')      # absolute path (linux)

ファイル拡張子を指定する必要があることに注意してください。.txtまたは.docなどのファイル拡張子は、エクスプローラで表示したときにデフォルトで非表示になるため、これはWindowsユーザーにとって特に重要です。

2番目の引数はでmoderデフォルトでは「読み取り専用」を意味します。それがまさにあなたがあなたの場合に必要なものです。

しかし、実際にファイルを作成したりファイルに書き込んだりする場合は、ここで別の引数が必要になります。概要が必要な場合は、優れた答えがあります

ファイルを読み取る場合は、を省略するmodeか、明示的に渡すことができます。

open(filename)
open(filename, 'r')

どちらもファイルを読み取り専用モードで開きます。Windowsでバイナリファイルを読み込む場合は、モードを使用する必要がありますrb

open(filename, 'rb')

他のプラットフォームでは、'b'(バイナリモード)は単に無視されます。


openファイルの操作方法を説明したので、常にclose再び必要になるということについて話しましょう。それ以外の場合は、プロセスが終了する(またはPythonがファイルハンドルをガベージする)まで、ファイルへのオープンファイルハンドルを保持します。

あなたが使うことができる間:

f = open(filename)
# ... do stuff with f
f.close()

その間に何かが発生して例外がスローされるopenと、ファイルを閉じることができませんclose。あなたはtryand を使うことでそれを避けることができますfinally

f = open(filename)
# nothing in between!
try:
    # do stuff with f
finally:
    f.close()

ただし、Pythonはよりきれいな構文を持つコンテキストマネージャーを提供します(ただし、openそれは上記tryとほぼ同じですfinally)。

with open(filename) as f:
    # do stuff with f
# The file is always closed after the with-scope ends.

最後のアプローチは、Pythonでファイルを開くための推奨アプローチです。

ファイルを読み取る

さて、あなたはファイルを開いたので、それをどのように読むのですか?

openこの関数は返すfileオブジェクトを、それはニシキヘビの反復プロトコルをサポートしています。各反復はあなたに線を与えます:

with open(filename) as f:
    for line in f:
        print(line)

これにより、ファイルの各行が印刷されます。ただし、各行\nの最後には改行文字が含まれていることに注意してください(Pythonがユニバーサル改行をサポートして構築されているかどうかを確認したい場合があります。それ以外の場合は\r\n、Windowsまたは\rMacでも改行として使用できます)。それを望まない場合は、最後の文字(またはWindowsでは最後の2文字)を削除するだけで済みます。

with open(filename) as f:
    for line in f:
        print(line[:-1])

しかし、最後の行には必ずしも末尾の改行があるとは限らないため、使用しないでください。末尾の改行で終わっているかどうかを確認し、そうである場合は削除します。

with open(filename) as f:
    for line in f:
        if line.endswith('\n'):
            line = line[:-1]
        print(line)

ただし、文字列\n末尾からすべての空白(文字を含む)を削除するだけでかまいません。これにより、他のすべての末尾の空白も削除されるため、これらが重要である場合は注意が必要です。

with open(filename) as f:
    for line in f:
        print(f.rstrip())

ただし、行が\r\n(Windowsの「改行」)で終わっている場合.rstrip()\r

内容をリストとして保存

ファイルを開いて読み取る方法がわかったので、今度は内容をリストに保存します。最も簡単なオプションは、list関数を使用することです。

with open(filename) as f:
    lst = list(f)

末尾の改行を削除したい場合は、代わりにリスト内包表記を使用できます。

with open(filename) as f:
    lst = [line.rstrip() for line in f]

あるいはもっと簡単です:オブジェクトの.readlines()メソッドはfileデフォルトlistで次の行を返します:

with open(filename) as f:
    lst = f.readlines()

これには、末尾の改行文字も含まれます。それらが不要な場合は[line.rstrip() for line in f]、メモリ内のすべての行を含む2つのリストを保持しないようにするため、この方法をお勧めします。

目的の出力を取得するための追加オプションがありますが、それはむしろ「最適ではありません」:read文字列内の完全なファイルと改行で分割:

with open(filename) as f:
    lst = f.read().split('\n')

または:

with open(filename) as f:
    lst = f.read().splitlines()

split文字が含まれていないため、これらは末尾の改行を自動的に処理します。ただし、ファイルを文字列およびメモリ内の行のリストとして保持するため、これらは理想的ではありません。

概要

  • with open(...) as f自分でファイルを閉じる必要がないため、ファイルを開くときに使用します。例外が発生してもファイルを閉じます。
  • fileオブジェクトは反復プロトコルをサポートしているため、ファイルを1行ずつ読み取るのはと同じくらい簡単for line in the_file_object:です。
  • 利用可能な関数/クラスのドキュメントを常に参照してください。ほとんどの場合、タスクまたは少なくとも1つまたは2つの優れたタスクに完全に一致します。この場合は当然の選択readlines()ですが、行をリストに格納する前に処理したい場合は、単純なリスト内包をお勧めします。

最後のアプローチは、Pythonでファイルを開くための推奨アプローチです。ではなぜそれが最後なのでしょうか?大多数の人は、先に進む前に、最初の数行の回答を一目見ているだけではありませんか?
AMC

@AMC答えを書いたとき、私はそれについてあまり考えていませんでした。私はそれを答えの一番上に置くべきだと思いますか?
MSeifert

そうだね。また、あなたがPython 2について言及していることにも気付いたので、それも更新される可能性があります。
AMC

ああ、質問はもともとpython-2.xとタグ付けされていました。より一般的に更新することは理にかなっています。次回はそちらに来るか確認します。あなたの提案をありがとう。とても有難い!
MSeifert

42

ファイルの行をリストに読み込むクリーンでPython的な方法


何よりもまず、ファイルを開いてその内容を効率的かつpythonicな方法で読み取ることに集中する必要があります。これは私が個人的に好まない方法の例です:

infile = open('my_file.txt', 'r')  # Open the file for reading.

data = infile.read()  # Read the contents of the file.

infile.close()  # Close the file since we're done using it.

代わりに、以下の方法でファイルを読み取りと書き込みの両方で開くことをお勧めします。ファイルは非常にクリーンであり、使用後にファイルを閉じる追加の手順を必要としないためです。以下のステートメントでは、ファイルを読み取り用に開いて、変数「infile」に割り当てています。このステートメント内のコードの実行が完了すると、ファイルは自動的に閉じられます。

# Open the file for reading.
with open('my_file.txt', 'r') as infile:

    data = infile.read()  # Read the contents of the file into memory.

このデータは反復可能で、効率的で、柔軟性があるため、今度はこのデータをPythonリストに取り込むことに集中する必要があります。あなたの場合、望ましい目標は、テキストファイルの各行を個別の要素にすることです。これを行うには、splitlines()メソッドを次のように使用します。

# Return a list of the lines, breaking at line boundaries.
my_list = data.splitlines()

最終製品:

# Open the file for reading.
with open('my_file.txt', 'r') as infile:

    data = infile.read()  # Read the contents of the file into memory.

# Return a list of the lines, breaking at line boundaries.
my_list = data.splitlines()

コードのテスト:

  • テキストファイルの内容:
     A fost odatã ca-n povesti,
     A fost ca niciodatã,
     Din rude mãri împãrãtesti,
     O prea frumoasã fatã.
  • テスト目的でステートメントを印刷します。
    print my_list  # Print the list.

    # Print each line in the list.
    for line in my_list:
        print line

    # Print the fourth element in this list.
    print my_list[3]
  • 出力(Unicode文字のために見た目が異なる):
     ['A fost odat\xc3\xa3 ca-n povesti,', 'A fost ca niciodat\xc3\xa3,',
     'Din rude m\xc3\xa3ri \xc3\xaemp\xc3\xa3r\xc3\xa3testi,', 'O prea
     frumoas\xc3\xa3 fat\xc3\xa3.']

     A fost odatã ca-n povesti, A fost ca niciodatã, Din rude mãri
     împãrãtesti, O prea frumoasã fatã.

     O prea frumoasã fatã.

30

Python 3.4で導入されたpathlib、次のように、ファイルからテキストを読み取るための非常に便利な方法があります。

from pathlib import Path
p = Path('my_text_file')
lines = p.read_text().splitlines()

splitlines呼び出しは、ファイルの内容全体を含む文字列から、ファイル内の行のリストに変更するものです)。

pathlib便利な機能がたくさんあります。read_textは素晴らしく簡潔なので、ファイルを開いたり閉じたりする必要はありません。ファイルを処理するために必要なことがすべて一度にすべて読み込まれる場合は、これが適切な選択です。


29

ファイルにリスト内包表記を使用するもう1つのオプションを次に示します。

lines = [line.rstrip() for line in open('file.txt')]

ほとんどの作業はPythonインタープリター内で行われるため、これはより効率的な方法です。


10
rstrip()潜在的な; だけでなく、すべての末尾の空白を削除し\nます。使用します.rstrip('\n')
mklement0

これはまた、すべてのPython実装を読み取った後にファイルが閉じられることを保証しません(CPythonではメインのPython実装ですが、閉じられます)。
Mark Amery

1
ほとんどの作業はPythonインタープリター内で行われるため、これはより効率的な方法です。どういう意味ですか?
AMC

28
f = open("your_file.txt",'r')
out = f.readlines() # will append in the list out

変数outは、必要なもののリスト(配列)です。あなたはどちらかをすることができます:

for line in out:
    print (line)

または:

for line in f:
    print (line)

同じ結果が得られます。


27

Python 2およびPython 3でテキストファイルを読み書きします。Unicodeで動作します

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Define data
lines = ['     A first string  ',
         'A Unicode sample: €',
         'German: äöüß']

# Write text file
with open('file.txt', 'w') as fp:
    fp.write('\n'.join(lines))

# Read text file
with open('file.txt', 'r') as fp:
    read_lines = fp.readlines()
    read_lines = [line.rstrip('\n') for line in read_lines]

print(lines == read_lines)

注目すべきこと:

  • withは、いわゆるコンテキストマネージャです。開いているファイルが再び閉じられることを確認します。
  • ここですべてのソリューションは、単に空白を削除するため.strip()、単に作成するか、または.rstrip()再生に失敗しlinesます。

一般的なファイル末尾

.txt

より高度なファイルの書き込み/読み取り

アプリケーションでは、次のことが重要になる場合があります。

  • 他のプログラミング言語によるサポート
  • 読み取り/書き込みパフォーマンス
  • コンパクト(ファイルサイズ)

参照:データのシリアル化形式の比較

構成ファイルを作成する方法を探している場合は、短い記事「Pythonでの構成ファイル」を読んでください。


26

別のオプションはnumpy.genfromtxt、例えばです:

import numpy as np
data = np.genfromtxt("yourfile.dat",delimiter="\n")

これdataにより、ファイル内の行数と同じ数のNumPy配列が作成されます。


25

コマンドラインまたはstdinからファイルを読み取りたい場合は、fileinputモジュールを使用することもできます。

# reader.py
import fileinput

content = []
for line in fileinput.input():
    content.append(line.strip())

fileinput.close()

そのようにそれにファイルを渡します:

$ python reader.py textfile.txt 

詳細はこちら:http : //docs.python.org/2/library/fileinput.html


20

それを行う最も簡単な方法

簡単な方法は次のとおりです。

  1. ファイル全体を文字列として読み取る
  2. 文字列を行ごとに分割する

1行で、次のようになります。

lines = open('C:/path/file.txt').read().splitlines()

ただし、これは2つのバージョンのコンテンツをメモリに保存するため、非常に非効率的な方法です(おそらく、小さなファイルでは大きな問題ではありませんが)。[Mark Ameryに感謝]。

2つの簡単な方法があります。

  1. ファイルをイテレータとして使用する
lines = list(open('C:/path/file.txt'))
# ... or if you want to have a list without EOL characters
lines = [l.rstrip() for l in open('C:/path/file.txt')]
  1. Python 3.4以降を使用pathlibしている場合は、プログラムの他の操作に使用できるファイルのパスを作成するために、より適切に使用します。
from pathlib import Path
file_path = Path("C:/path/file.txt") 
lines = file_path.read_text().split_lines()
# ... or ... 
lines = [l.rstrip() for l in file_path.open()]

これは悪いアプローチです。1つには、を呼び出すこと.read().splitlines()は、単にを呼び出すよりも「単純」ではありません.readlines()。もう1つは、メモリ効率が悪いことです。ファイルのコンテンツの2つのバージョン(によって返される単一の文字列.read()とによって返される文字列のリストsplitlines())を一度にメモリに不必要に保存する必要があります。
Mark Amery

@MarkAmery True。これを強調してくれてありがとう。回答を更新しました。
Jean-Francois T.

14

splitlines()関数を使用するだけです。ここに例があります。

inp = "file.txt"
data = open(inp)
dat = data.read()
lst = dat.splitlines()
print lst
# print(lst) # for python 3

出力には、行のリストがあります。


を使用する場合に比べてメモリ効率が悪い.readlines()。これにより、ファイルコンテンツの2つのコピーが一度にメモリに配置されます(1つは単一の巨大な文字列、もう1つは行のリスト)。
Mark Amery

11

非常に大きな/巨大なファイルに直面し、より速く読みたい場合(Topcoder / Hackerrankコーディングの競争に参加していると想像してください)、一度にかなり大きな行のチャンクをメモリバッファーに読み込むのではなく、ファイルレベルで1行ずつ繰り返すだけです。

buffersize = 2**16
with open(path) as f: 
    while True:
        lines_buffer = f.readlines(buffersize)
        if not lines_buffer:
            break
        for line in lines_buffer:
            process(line)

プロセス(ライン)は何をしますか?そのような変数が定義されていないというエラーが表示されます。何かをインポートする必要があると思うので、multiprocessing.Processをインポートしようとしましたが、そうではありません。詳しく説明してもらえますか?ありがとう
Newskooler 2017

1
process(line)データを処理するために実装する必要がある関数です。たとえば、その行の代わりにを使用print(line)すると、lines_bufferから各行が出力されます。
Khanal 2017

f.readlines(buffersize)は不変のバッファーを返します。バッファに直接読み込む場合は、readinto()関数を使用する必要があります。私ははるかに速くなります。
David Dehghan

7

いくつかの追加の利点を使用してそれを行う最も簡単な方法は次のとおりです。

lines = list(open('filename'))

または

lines = tuple(open('filename'))

または

lines = set(open('filename'))

の場合set、行の順序が保持されず、重複する行が削除されることを忘れないでください。

以下に、@ MarkAmeryからの重要な補足を追加しました。

.closeファイルオブジェクトを呼び出すこともwithステートメントを使用することもないため、一部のPython実装では、読み取り後にファイルが閉じられず、プロセスが開いているファイルハンドルをリークする場合があります

ではCPythonの(通常のPythonファイルオブジェクトはすぐにガベージコレクションを取得しますと、これはファイルを閉じますが、それはそれにもかかわらず、一般的のような何かをすることがベストプラクティスと考えられていますので、ほとんどの人が使用することを実装)、これは問題ではありません

with open('filename') as f: lines = list(f) 

使用しているPythonの実装に関係なく、ファイルが確実に閉じられるようにします。


1
.closeファイルオブジェクトを呼び出すこともwithステートメントを使用することもないため、一部のPython実装では、読み取り後にファイルが閉じられず、プロセスが開いているファイルハンドルをリークする場合があります。CPython(ほとんどの人が使用する通常のPython実装)では、ファイルオブジェクトがすぐにガベージコレクションされてファイルが閉じられるため、これは問題にはなりませんが、それでも、次のことwith open('filename') as f: lines = list(f)を確実にするために何かを行うことが一般的にはベストプラクティスと見なされます。ファイルは、使用しているPython実装に関係なく閉じられます。
Mark Amery

素晴らしいコメント@MarkAmeryをありがとう!ほんとうにありがとう。
simhumileco

1
@simhumilecoなぜ最良の(正しい)ソリューションが持続するのですか?
AMC

@AMCは、最初に、最も単純な方法を示し、推論の一貫性を保つためです。
simhumileco

また、短くて読みやすいように回答していただければ幸いです。
simhumileco

4

これを使って:

import pandas as pd
data = pd.read_csv(filename) # You can also add parameters such as header, sep, etc.
array = data.values

dataデータフレームタイプであり、値を使用してndarrayを取得します。を使用してリストを取得することもできarray.tolist()ます。


pandas.read_csv()CSVデータを読み取るためのものですが、ここではどのように適切ですか?
AMC

4

概要と概要

を使用してfilenamePath(filename)オブジェクトからのファイルを処理するか、直接を使用してopen(filename) as f、次のいずれかを実行します。

  • list(fileinput.input(filename))
  • 使用with path.open() as f、呼び出しf.readlines()
  • list(f)
  • path.read_text().splitlines()
  • path.read_text().splitlines(keepends=True)
  • 反復処理fileinput.inputまたはfそしてlist.append時に各ライン1
  • fバインドされたlist.extendメソッドに渡す
  • fリスト内包表記で使用する

以下にそれぞれのユースケースを説明します。

Pythonでは、ファイルを1行ずつ読み取るにはどうすればよいですか?

これは素晴らしい質問です。最初に、いくつかのサンプルデータを作成します。

from pathlib import Path
Path('filename').write_text('foo\nbar\nbaz')

ファイルオブジェクトは遅延イテレータなので、反復するだけです。

filename = 'filename'
with open(filename) as f:
    for line in f:
        line # do something with the line

または、複数のファイルがある場合はfileinput.input、別の遅延イテレータを使用します。ファイルが1つだけの場合:

import fileinput

for line in fileinput.input(filename): 
    line # process the line

または、複数のファイルの場合は、ファイル名のリストを渡します。

for line in fileinput.input([filename]*2): 
    line # process the line

繰り返しにfなりfileinput.inputますが、上記の両方は遅延遅延イテレータです。イテレータは1回しか使用できないため、冗長性を回避しながら機能コードを提供するためにfileinput.input(filename)、ここから少し簡潔な箇所を使用します。

Pythonでは、ファイルを1行ずつリストに読み込むにはどうすればよいですか?

ああ、でも何らかの理由でリストに入れたいですか?できればそれは避けたい。しかし、あなたが主張するなら...の結果をfileinput.input(filename)toに渡すだけですlist

list(fileinput.input(filename))

もう一つの直接的な答えがコールにあるf.readlines(別売まで、ファイルの内容を返し、hintあなたはので、文字の数ができ、複数のリストそのように、このアップを破ります)。

このファイルオブジェクトには2つの方法でアクセスできます。1つの方法は、open組み込みにファイル名を渡すことです。

filename = 'filename'

with open(filename) as f:
    f.readlines()

または、pathlibモジュールの新しいPathオブジェクトを使用します(これは私が非常に好きになり、今後使用します):

from pathlib import Path

path = Path(filename)

with path.open() as f:
    f.readlines()

list また、ファイルイテレータを使用してリストを返します。これも非常に直接的な方法です。

with path.open() as f:
    list(f)

分割する前にテキスト全体を1つの文字列としてメモリに読み込むことを気にしない場合は、Pathオブジェクトとsplitlines()文字列メソッドを使用して、これをワンライナーとして実行できます。デフォルトでsplitlinesは、改行を削除します。

path.read_text().splitlines()

改行を保持したい場合は、次を渡しkeepends=Trueます:

path.read_text().splitlines(keepends=True)

ファイルを1行ずつ読み取り、リストの最後に各行を追加したいと思います。

いくつかの方法で簡単に最終結果を示したので、これは少し愚かなことです。しかし、リストを作成するときに、行をフィルタリングまたは操作する必要がある場合があるので、このリクエストをユーモアにつなげましょう。

を使用list.appendすると、追加する前に各行をフィルタリングまたは操作できます。

line_list = []
for line in fileinput.input(filename):
    line_list.append(line)

line_list

を使用list.extendするともう少し直接的になり、既存のリストがある場合はおそらく便利です。

line_list = []
line_list.extend(fileinput.input(filename))
line_list

または、もっと慣用的に、代わりにリスト内包表記を使用して、必要に応じてリスト内包をマッピングしてフィルタリングすることもできます。

[line for line in fileinput.input(filename)]

またはさらに直接、円を閉じるには、リストに渡して、行を操作せずに新しいリストを直接作成します。

list(fileinput.input(filename))

結論

ファイルからリストに行を取得する多くの方法を見てきましたが、大量のデータをリストに具体化せず、可能であればPythonの遅延反復を使用してデータを処理することをお勧めします。

つまり、fileinput.inputまたはを優先しwith path.open() as fます。


4

文書に空の行もある場合は、コンテンツを読み込んで、filter空の文字列要素を防ぐためにパススルーします

with open(myFile, "r") as f:
    excludeFileContent = list(filter(None, f.read().splitlines()))

1
これは非Pythonicなので、注意してください。
AMC

3

NumPyでloadtxtコマンドを使用することもできます。これはgenfromtxtよりも少ない条件をチェックするので、より高速になる場合があります。

import numpy
data = numpy.loadtxt(filename, delimiter="\n")

2

私は以下を使用するのが好きです。すぐに行を読みます。

contents = []
for line in open(filepath, 'r').readlines():
    contents.append(line.strip())

またはリスト内包表記を使用:

contents = [line.strip() for line in open(filepath, 'r').readlines()]

2
の必要はなくreadlines()、メモリのペナルティも発生します。(テキスト)ファイルを繰り返すと各行が順番に表示されるので、単純に削除できます。
エリックOレビゴット2018年

2
withステートメントを使用してファイルを開く(および暗黙的に閉じる)必要があります。
アランフェイ

2

以下の方法のいずれかを試してみます。私が使用するサンプルファイルの名前はdummy.txtです。ここでファイルを見つけることができます。ファイルはコードと同じディレクトリにあると思います(fpath適切なファイル名とフォルダーパスを含めるように変更できます)。

以下の両方の例で、必要なリストはによって提供されlstます。

1.>最初の方法

fpath = 'dummy.txt'
with open(fpath, "r") as f: lst = [line.rstrip('\n \t') for line in f]

print lst
>>>['THIS IS LINE1.', 'THIS IS LINE2.', 'THIS IS LINE3.', 'THIS IS LINE4.']

2.>第二の方法、一つは使用できcsv.reader Python標準ライブラリからモジュール

import csv
fpath = 'dummy.txt'
with open(fpath) as csv_file:
    csv_reader = csv.reader(csv_file, delimiter='   ')
    lst = [row[0] for row in csv_reader] 

print lst
>>>['THIS IS LINE1.', 'THIS IS LINE2.', 'THIS IS LINE3.', 'THIS IS LINE4.']

2つの方法のいずれかを使用できます。の作成にかかる時間lstは、2つの方法でほぼ同じです。


1
2番目のアプローチの利点は何ですか?エッジケース(区切り文字、引用符)を追加する追加のライブラリを呼び出すのはなぜですか?
チャーリーハーディング

何のためのdelimiter=' '議論ですか?
AMC

2

次に、ファイルI / Oを簡略化するために使用するPython(3)ヘルパーライブラリクラスを示します。

import os

# handle files using a callback method, prevents repetition
def _FileIO__file_handler(file_path, mode, callback = lambda f: None):
  f = open(file_path, mode)
  try:
    return callback(f)
  except Exception as e:
    raise IOError("Failed to %s file" % ["write to", "read from"][mode.lower() in "r rb r+".split(" ")])
  finally:
    f.close()


class FileIO:
  # return the contents of a file
  def read(file_path, mode = "r"):
    return __file_handler(file_path, mode, lambda rf: rf.read())

  # get the lines of a file
  def lines(file_path, mode = "r", filter_fn = lambda line: len(line) > 0):
    return [line for line in FileIO.read(file_path, mode).strip().split("\n") if filter_fn(line)]

  # create or update a file (NOTE: can also be used to replace a file's original content)
  def write(file_path, new_content, mode = "w"):
    return __file_handler(file_path, mode, lambda wf: wf.write(new_content))

  # delete a file (if it exists)
  def delete(file_path):
    return os.remove() if os.path.isfile(file_path) else None

次にFileIO.lines、次のように関数を使用します。

file_ext_lines = FileIO.lines("./path/to/file.ext"):
for i, line in enumerate(file_ext_lines):
  print("Line {}: {}".format(i + 1, line))

ことを覚えておいてくださいmode"r"デフォルト)とfilter_fn(デフォルトでは空行をチェック)のパラメータはオプションです。

readwriteおよびdeleteメソッドを削除して、そのままにすることもできますFileIO.lines。または、と呼ばれる別のメソッドに変換することもできread_linesます。


lines = FileIO.lines(path)本当に十分なよりも簡単with open(path) as f: lines = f.readlines()このヘルパーの存在を正当化しますか?たとえば、通話あたり17文字を節約できます。(そして、ほとんどの場合、パフォーマンスとメモリの理由から、とにかくその行をリストに読み込むのではなく、ファイルオブジェクトを直接ループしたいので、これを頻繁に使用することすらしません!)多くの場合、小さなユーティリティ関数を作成するファンですが、これは、標準ライブラリですでに短く簡単な何かを書くための新しい方法を不必要に作成しているだけだと私には感じています。
Mark Amery

@MarkAmeryが言ったことに加えて、なぜこれにクラスを使用するのですか?
AMC

1

コマンドラインバージョン

#!/bin/python3
import os
import sys
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
filename = dname + sys.argv[1]
arr = open(filename).read().split("\n") 
print(arr)

次で実行:

python3 somefile.py input_file_name.txt
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.