如何在已经包含文本的行上将字典写入CSV文件?

时间:2018-06-22 01:58:32

标签: python csv dictionary file-writing

我正在使用python 3.6.0。我以前已经将字典写到CSV文件,但是从来没有在已经包含文本的行上写过字典。我现在遇到麻烦了。这是我的代码:

import csv

f='/Users/[my name]/Documents/Webscraper/tests/output_sheet_1.csv'
bigdict = {'ex_1': 1, 'ex_2': 2, 'ex_3': 3}
with open(f, 'r+') as file:
    fieldnames=['ex_1','ex_2','ex_3']
    writer = csv.DictWriter(file, fieldnames=fieldnames,delimiter=',')
    if '\n' not in file.readline()[-1]:
        file.write('\n')
    writer.writerow(bigdict)

运行此命令时,python将字典添加到包含字段名称的行之后的第一行,从字段名称下面的最后一个单元格开始。换句话说,第一行包含许多条目,包括最后三个单元格中的ex_1ex_2ex_3。在第二行中,我存储在所有单元格中的值,但ex_1ex_2ex_3下的值为空白。 Python在1下写入整数ex_3,并在其右边的单元格中写入23

我想重新放置它们,以便每个数字都位于其各自的字段名称单元格下方。我该怎么做,为什么会这样?谢谢。

1 个答案:

答案 0 :(得分:1)

您有两个问题:

  1. 如果没有文件(或者文件为空),则需要添加标题行。

  2. 如果要将新行追加到现有文件中,则试图确保文件中的最后一个字符是换行符。 writerow()将添加尾随换行符,因此通常这不会有问题。但是,如果文件已被手动编辑并且缺少尾随的换行符,则这将导致新行被追加到最后一行的末尾。

可以通过首先测试文件的大小来解决第一个问题。如果它是0,则它存在但为空。如果文件不存在,则会引发OSError异常。 write_header用于发出信号。

第二个问题比较棘手。如果以二进制模式打开文件,则可以查找文件的最后一个字节并读入。可以检查它是否为换行符。如果您的文件曾经使用过另一种编码,则需要对此进行更改。然后可以在追加模式下重新打开文件并写入新行。

可以全部完成以下操作:

import csv

filename = '/Users/[my name]/Documents/Webscraper/tests/output_sheet_1.csv'
bigdict = {'ex_1': 1, 'ex_2': 2, 'ex_3': 3}

# Does the file exist? If not (or it is empty) write a header
try:
    write_header = os.path.getsize(filename) == 0
except OSError:
    write_header = True

# If the file exists, does it end with a newline?    
if write_header:
    no_ending_newline = False
else:
    with open(filename, 'rb') as f_input:
        f_input.seek(-1, 2)     # move to the last byte of the file
        no_ending_newline = f_input.read() != b'\n'

with open(filename, 'a', newline='') as f_output:
    fieldnames = ['ex_1','ex_2','ex_3']
    csv_writer = csv.DictWriter(f_output, fieldnames=fieldnames)

    if write_header:
        csv_writer.writeheader()

    if no_ending_newline:
        f_output.write('\n')

    csv_writer.writerow(bigdict)