我正在使用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_1
,ex_2
和ex_3
。在第二行中,我存储在所有单元格中的值,但ex_1
,ex_2
和ex_3
下的值为空白。 Python在1
下写入整数ex_3
,并在其右边的单元格中写入2
和3
。
我想重新放置它们,以便每个数字都位于其各自的字段名称单元格下方。我该怎么做,为什么会这样?谢谢。
答案 0 :(得分:1)
您有两个问题:
如果没有文件(或者文件为空),则需要添加标题行。
如果要将新行追加到现有文件中,则试图确保文件中的最后一个字符是换行符。 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)