Вопрос-Ответ

How do I concatenate text files in Python?

Как мне объединить текстовые файлы в Python?

У меня есть список из 20 имен файлов, например, ['file1.txt', 'file2.txt', ...]. Я хочу написать скрипт на Python для объединения этих файлов в новый файл. Я мог бы открывать каждый файл с помощью f = open(...), читать строку за строкой, вызывая f.readline(), и записывать каждую строку в этот новый файл. Мне это кажется не очень "элегантным", особенно та часть, где я должен читать / записывать построчно.

Есть ли более "элегантный" способ сделать это в Python?

Переведено автоматически
Ответ 1

Это должно сработать

Для больших файлов:

filenames = ['file1.txt', 'file2.txt', ...]
with open('path/to/output/file', 'w') as outfile:
for fname in filenames:
with open(fname) as infile:
for line in infile:
outfile.write(line)

Для небольших файлов:

filenames = ['file1.txt', 'file2.txt', ...]
with open('path/to/output/file', 'w') as outfile:
for fname in filenames:
with open(fname) as infile:
outfile.write(infile.read())

... и еще один интересный вариант, о котором я подумал:

filenames = ['file1.txt', 'file2.txt', ...]
with open('path/to/output/file', 'w') as outfile:
for line in itertools.chain.from_iterable(itertools.imap(open, filnames)):
outfile.write(line)

К сожалению, этот последний метод оставляет несколько открытых файловых дескрипторов, о которых в любом случае должен позаботиться GC. Я просто подумал, что это интересно

Ответ 2

Использовать shutil.copyfileobj.

Он автоматически считывает входные файлы фрагмент за фрагментом для вас, что более эффективно, и считывает входные файлы в и будет работать, даже если некоторые из входных файлов слишком велики, чтобы поместиться в памяти:

import shutil

with open('output_file.txt','wb') as wfd:
for f in ['seg1.txt','seg2.txt','seg3.txt']:
with open(f,'rb') as fd:
shutil.copyfileobj(fd, wfd)
Ответ 3

Именно для этого и предназначен fileinput:

import fileinput
with open(outfilename, 'w') as fout, fileinput.input(filenames) as fin:
for line in fin:
fout.write(line)

Для данного варианта использования это действительно не намного проще, чем просто перебирать файлы вручную, но в других случаях очень удобно иметь единый итератор, который перебирает все файлы, как если бы они были одним файлом. (Кроме того, тот факт, что fileinput закрывает каждый файл, как только это сделано, означает, что нет необходимости в with или close каждом из них, но это всего лишь экономия на одной строке, не такая уж большая проблема.)

В fileinput есть несколько других замечательных функций, таких как возможность вносить изменения в файлы на месте, просто фильтруя каждую строку.


Как отмечено в комментариях и обсуждено в другом посте, fileinput для Python 2.7 не будет работать так, как указано. Здесь небольшое изменение, чтобы сделать код совместимым с Python 2.7

with open('outfilename', 'w') as fout:
fin = fileinput.input(filenames)
for line in fin:
fout.write(line)
fin.close()
Ответ 4
outfile.write(infile.read()) # time: 2.1085190773010254s
shutil.copyfileobj(fd, wfd, 1024*1024*10) # time: 0.60599684715271s

Простой тест показывает, что shutil работает лучше.

2023-12-31 10:23 python