У меня есть список из 20 имен файлов, например, ['file1.txt', 'file2.txt', ...]. Я хочу написать скрипт на Python для объединения этих файлов в новый файл. Я мог бы открывать каждый файл с помощью f = open(...), читать строку за строкой, вызывая f.readline(), и записывать каждую строку в этот новый файл. Мне это кажется не очень "элегантным", особенно та часть, где я должен читать / записывать построчно.
Есть ли более "элегантный" способ сделать это в Python?
Переведено автоматически
Ответ 1
Это должно сработать
Для больших файлов:
filenames = ['file1.txt', 'file2.txt', ...] withopen('path/to/output/file', 'w') as outfile: for fname in filenames: withopen(fname) as infile: for line in infile: outfile.write(line)
Для небольших файлов:
filenames = ['file1.txt', 'file2.txt', ...] withopen('path/to/output/file', 'w') as outfile: for fname in filenames: withopen(fname) as infile: outfile.write(infile.read())
... и еще один интересный вариант, о котором я подумал:
filenames = ['file1.txt', 'file2.txt', ...] withopen('path/to/output/file', 'w') as outfile: for line in itertools.chain.from_iterable(itertools.imap(open, filnames)): outfile.write(line)
К сожалению, этот последний метод оставляет несколько открытых файловых дескрипторов, о которых в любом случае должен позаботиться GC. Я просто подумал, что это интересно
Он автоматически считывает входные файлы фрагмент за фрагментом для вас, что более эффективно, и считывает входные файлы в и будет работать, даже если некоторые из входных файлов слишком велики, чтобы поместиться в памяти:
import shutil
withopen('output_file.txt','wb') as wfd: for f in ['seg1.txt','seg2.txt','seg3.txt']: withopen(f,'rb') as fd: shutil.copyfileobj(fd, wfd)
import fileinput withopen(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
withopen('outfilename', 'w') as fout: fin = fileinput.input(filenames) for line in fin: fout.write(line) fin.close()