将行添加到csv文件而不创建中间副本

时间:2014-09-11 16:36:17

标签: python

如何通过编辑将行添加到csvfile?我想避免写入临时文件然后替换原始文件(伪代码)的模式:

add_records_to_csv(newdata, infile, tmpfile)
delete(infile)
rename(tmpfile, infile)

这是实际的功能。 “#< - ”这些行是我想要摆脱和/或压缩成更直接的东西:

def add_records_to_csv(dic, csvfile):
    """ Append a dictionary to a CSV file.
        Adapted from http://pymotw.com/2/csv/
    """
    f_old = open(csvfile, 'rb')                         # <--
    csv_old = csv.DictReader(f_old)                     # <--

    fpath, fname = os.path.split(csvfile)               # <--
    csvfile_new = os.path.join(fpath, 'new_' + fname )  # <--
    print(csvfile_new)                                  # <--
    f = open(csvfile_new, 'wb')                         # <--

    try:
        fieldnames = sorted(set(dic.keys() + csv_old.fieldnames))
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        headers = dict( (n,n) for n in fieldnames )
        writer.writerow(headers)
        for row in csv_old:
            writer.writerow(row)
        writer.writerow(dic)
    finally:
        f_old.close()
        f.close()
    return csvfile_new

2 个答案:

答案 0 :(得分:3)

一般情况下这是不可能的。以下是您的代码:

的原因
fieldnames = sorted(set(dic.keys() + csv_old.fieldnames))

对我而言,这表示至少在某些情况下您的新行包含的行不包含在前一行中。当您添加这样的行时,除了在末尾添加新行之外,还必须更新文件的标题(第一行)。如果您需要按字母顺序排列列名,那么您可能必须重新排列所有其他行中的字段,以保留列的顺序。

因为您可能需要编辑文件的第一行,除了在末尾添加新行并可能编辑其间的所有行之外,还没有合理的方法使其在原地工作

我的建议是提前尝试弄清楚您可能需要包含的所有字段/列,以便保证您的程序永远不必编辑标题,只需添加新行即可。

答案 1 :(得分:1)

如果您的新行具有与现有记录相同的结构,则以下内容将起作用:

import csv

def append_record_to_csv(dic, csvfile):
    with open(csvfile, 'rb') as f:
        # discover order of field names in header row
        fieldnames = next(csv.reader(f))   
    with open(csvfile, 'ab') as f:
        # assumes that dic contains only fieldnames in csv file
        dwriter = csv.DictWriter(f, fieldnames=fieldnames) 
        dwriter.writerow(dic)

另一方面,如果您的新行作为与现有行不同的结构,则csv文件可能是错误的文件格式。为了向csv文件添加新列,需要编辑每一行。这种方法的性能非常糟糕,并且对于大型csv文件会非常明显。