csv.DictReader和csv.DictWriter类应该工作良好(请参见Python docs)。像这样的: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的,在没有newline=""的CSV模块中会发生奇怪的事情。对于Python2,删除此项。
此时,line是一个dict,字段名作为键,列数据作为值。可以指定如何处理DictReader和DictWriter构造函数中的空值或未知值。
此方法不应耗尽内存,因为它从不同时加载整个文件。