100 個のファイル (各ファイルには 2 つの列が含まれます) からエントリを追加し、それらを新しいファイル (これにも 2 つの列が含まれます) に書き込む方法について質問があります。
4 に答える
Torxedアプローチに触発されたよりスケーラブルな方法
from os import walk
from os.path import abspath
with open('output.txt', 'wb') as o:
for root, folders, files in walk('./path/'):
for filename in files:
with open(abspath(root + '/' + filename), 'rb') as i:
for line in i:
o.write(line)
これらの100個のファイルすべてを見つけるためのソリューションが必要かどうかわかりませんでしたか?もしそうなら、それらすべてを読み取り、結合されたファイルに書き込むことを含む1つのアプローチがあります:
from os import walk
from os.path import abspath
lines = []
for root, folders, files in walk('./path/'):
for file in files:
fh = open(abspath(root + '/' + file), 'rb')
lines.append(fh.read())
fh.close()
# break if you only want the first level of your directory tree
o = open('output.txt', 'wb')
o.write('\n'.join(lines))
o.close()
「メモリ効率の高い」ソリューションを実行することもできます。
from os import walk
from os.path import abspath
o = open('output.txt', 'wb')
for root, folders, files in walk('./path/'):
for file in files:
fh = open(abspath(root + '/' + file), 'rb')
for line in fh.readline():
o.write(line)
del line
fh.close()
del fh
# break if you only want the first level of your directory tree
o.close()
これの多くはPython内で自動化されていますが(私は思う)、ファイルを閉じた後、変数名を再利用する前後にメモリからオブジェクトを削除できる場合は、怠惰かどうかはわかりません。
それらをチェーンしますか?つまり、ファイル 1 のすべての行が必要ですか、次にファイル 2 のすべての行が必要ですか? それともそれらをマージしますか? ファイル 1 の 1 行目、ファイル 2 の 1 行目、...
最初のケース:
from itertools import chain
filenames = ...
file_handles = [open(fn) for fn in filenames]
with open("output.txt", "w") as out_fh:
for line in chain(file_handles):
out_fh.write(line)
for fh in file_handles:
fh.close()
2 番目のケースの場合:
from itertools import izip_longest
filenames = ...
file_handles = [open(fn) for fn in filenames]
with open("output.txt", "w") as out_fh:
for lines in izip_longest(*file_handles, fillvalue=None):
for line in lines:
if line is not None:
out_fh.write(line)
for fh in file_handles:
fh.close()
重要: ファイルを閉じることを忘れないでください。
@isedev が指摘したように、このアプローチは 100 個のファイルに対しては問題ありませんが、すべてのハンドルをすぐに開くため、数千のファイルでは機能しません。
この問題を克服したい場合は、オプション 1 (連鎖) のみが合理的です...
filenames = ...
with open("output.txt", "w") as out_fh:
for fn in filenames:
with open(fn) as fh:
for line in fh:
out_fh.write(line)
これは非常に過小評価されています。あなたの問題が何であるかは明らかではありません。
おそらくあなたは次のようなことをするでしょう:
entries = []
for f in ["file1.txt", "file2.txt", ..., "file100.txt"]:
entries.append(open(f).readlines())
o = open("output.txt", "w")
o.writelines(entries)
o.close()