【问题标题】:How do you write a dictionary to a CSV file on a line that already contains text?如何在已包含文本的行上将字典写入 CSV 文件?
【发布时间】:2018-12-01 10:35:11
【问题描述】:

我正在使用 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 在ex_3 下方写入整数1,并在其右侧的单元格中写入23

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

【问题讨论】:

  • 你尝试writer.writeheader(); writer.writrow(bigdict)了吗?
  • @pstatix 我尝试使用writer.writeheader(),但正如预期的那样,它创建了另一个标题,我不想要它,因为它已经在 CSV 文件中。我可以获取文件中的内容并将它们重写为一个新文件,但我不想这样做,因为文件非常大,我希望我的代码更有效率。
  • 我不认为这会像你想象的那样发生。仅仅因为这些标头存在并不意味着它们会自动写在它们下面,因为您已经实例化了DictWriter
  • 好的,据我所知,到目前为止,python 假定未列出的字段名下的所有内容都是空白的。如果不是这种情况,它基本上会破坏格式。话虽如此...将整个内容重写为新的 CSV 文件是最有效的方法吗?

标签: python csv dictionary file-writing


【解决方案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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2020-06-11
    • 2016-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多