Ответ 1
Классы csv.DictReader
и csv.DictWriter
должны хорошо работать (см. Документы Python). Что-то вроде этого:
import csv
inputs = ["in1.csv", "in2.csv"] # etc
# First determine the field names from the top line of each input file
# Comment 1 below
fieldnames = []
for filename in inputs:
with open(filename, "r", newline="") as f_in:
reader = csv.reader(f_in)
headers = next(reader)
for h in headers:
if h not in fieldnames:
fieldnames.append(h)
# Then copy the data
with open("out.csv", "w", newline="") as f_out: # Comment 2 below
writer = csv.DictWriter(f_out, fieldnames=fieldnames)
for filename in inputs:
with open(filename, "r", newline="") as f_in:
reader = csv.DictReader(f_in) # Uses the field names in this file
for line in reader:
# Comment 3 below
writer.writerow(line)
Комментарии выше:
- Вам нужно указать все возможные имена полей заранее на
DictWriter
, поэтому вам нужно дважды прокрутить все ваши файлы CSV: один раз, чтобы найти все заголовки и один раз прочитать данные. Нет лучшего решения, потому что все заголовки должны быть известны до того, какDictWriter
сможет написать первую строку. Эта часть будет более эффективной с использованием наборов вместо списков (операторin
в списке сравнительно медленный), но это не будет иметь большого значения для нескольких сотен заголовков. Наборы также потеряют детерминированное упорядочение списка - ваши столбцы будут выходить в другом порядке каждый раз, когда вы запускаете код. - Вышеприведенный код предназначен для Python 3, где в CSV-модуле происходят странные события без
newline=""
. Удалите это для Python 2. - В этот момент
line
- это dict с именами полей в виде ключей, а данные столбца - значениями. Вы можете указать, что делать с пустым или неизвестным значением в конструкторахDictReader
иDictWriter
.
Этот метод не должен заканчиваться из памяти, поскольку он никогда не загружает весь файл одновременно.