用Python编写的CSV文件在每行之间都有空行

时间:2010-07-27 22:14:43

标签: python windows csv

import csv

with open('thefile.csv', 'rb') as f:
  data = list(csv.reader(f))
  import collections
  counter = collections.defaultdict(int)

  for row in data:
        counter[row[10]] += 1


with open('/pythonwork/thefile_subset11.csv', 'w') as outfile:
    writer = csv.writer(outfile)
    for row in data:
        if counter[row[10]] >= 504:
           writer.writerow(row)

此代码读取thefile.csv,进行更改,并将结果写入thefile_subset1

但是,当我在Microsoft Excel中打开生成的csv时,每条记录后都会有一个额外的空行!

有没有办法让它不加一个额外的空白?

10 个答案:

答案 0 :(得分:655)

在Python 2中,使用模式outfile而不是'wb'打开'w'csv.writer直接将\r\n写入文件。如果您未在二进制模式下打开文件,它将写入\r\r\n,因为在Windows 文本模式下会将每个\n转换为{{ 1}}。

在Python 3中,所需语法已更改,因此请使用附加参数\r\n打开outfile

示例:

newline=''

文档链接

答案 1 :(得分:41)

以二进制模式打开文件“wb”在Python 3+中不起作用。或者更确切地说,在编写数据之前,您必须将数据转换为二进制数据。这只是一个麻烦。

相反,您应该将其保留在文本模式中,但将换行覆盖为空。像这样:

with open('/pythonwork/thefile_subset11.csv', 'w', newline='') as outfile:

答案 2 :(得分:12)

简单的答案是 csv文件应始终以二进制模式打开,无论是输入还是输出,否则在Windows上存在行结尾的问题。特别是在输出时,csv模块将写入\r\n(标准CSV行终止符),然后(在文本模式下)运行时将\n替换为\r\n(Windows标准行终止符)给出\r\r\n的结果。

摆弄lineterminator不是解决方案。

答案 3 :(得分:6)

注意:由于在Windows系统上添加额外行的方式,这似乎不是首选解决方案。如python document中所述:

  

如果csvfile是一个文件对象,那么它必须在平台上以“b”标志打开,这会产生影响。

Windows是一个有所作为的平台。虽然如下所述更改行终止符可能已经解决了问题,但是可以通过以二进制模式打开文件来完全避免该问题。有人可能会说这种解决方案更“优雅”。在这种情况下,使用行终止符“摆弄”可能会导致系统之间出现不可移植的代码,在unix系统上以二进制模式打开文件会导致无效。即。它导致交叉系统兼容的代码。

来自Python Docs

  

在Windows上,“b”附加到模式   以二进制模式打开文件,所以   还有像'rb','wb'这样的模式,   和'r + b'。 Windows上的Python制作了一个   文本和二进制之间的区别   文件;中的行尾字符   文本文件会自动更改   稍微读取或写入数据时。   这种幕后修改   文件数据适用于ASCII文本   文件,但它会破坏二进制数据   像在JPEG或EXE文件中那样。是   非常小心使用二进制模式时   读写这样的文件。上   Unix,附加一个'b'也没有坏处   到模式,所以你可以使用它   平台 - 独立于所有二进制文件   文件。

<强>原始

作为csv.writer的可选参数的一部分,如果您获得额外的空行,则可能需要更改lineterminator(info here)。以下示例改编自python页面csv docs.将其从'\ n'更改为它应该是什么。由于这只是在黑暗中解决问题,这可能会或可能不会奏效,但这是我最好的猜测。

>>> import csv
>>> spamWriter = csv.writer(open('eggs.csv', 'w'), lineterminator='\n')
>>> spamWriter.writerow(['Spam'] * 5 + ['Baked Beans'])
>>> spamWriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])

答案 4 :(得分:3)

我写这个答案w.r.t.到python 3,因为我最初遇到了同样的问题。

我应该使用PySerial从arduino获取数据,并将它们写在.csv文件中。我的案例中的每个阅读都以'\r\n'结束,因此换行始终将每一行分开。

就我而言,newline=''选项并不起作用。因为它显示了一些错误:

with open('op.csv', 'a',newline=' ') as csv_file:

ValueError: illegal newline value: ''

所以他们似乎不接受在这里遗漏新行。

仅在此处查看其中一个答案,我在编写器对象中提到了行终止符,如

writer = csv.writer(csv_file, delimiter=' ',lineterminator='\r')

这对于我跳过额外的换行符非常有用。

答案 5 :(得分:2)

自最初提出问题以来的十年中,许多其他答案已经过时。对于 Python3,答案就在 documentation 中:

<块引用>

如果 csvfile 是一个文件对象,它应该用newline=''打开

footnote 有更详细的解释:

<块引用>

如果没有指定 newline='',嵌入在引用字段中的换行符将不会被正确解释,并且在写入时使用 \r\n linendings 的平台上将添加一个额外的 \r。指定 newline='' 应该始终是安全的,因为 csv 模块会执行自己的(通用)换行处理。

答案 6 :(得分:1)

this answer借用,似乎最干净的解决方案是使用io.TextIOWrapper。我设法为自己解决了以下问题:

from io import TextIOWrapper

...

with open(filename, 'wb') as csvfile, TextIOWrapper(csvfile, encoding='utf-8', newline='') as wrapper:
    csvwriter = csv.writer(wrapper)
    for data_row in data:
        csvwriter.writerow(data_row)

以上答案与Python 2不兼容。要具有兼容性,我想一个人只需要将所有写逻辑包装在if块中即可:

if sys.version_info < (3,):
    # Python 2 way of handling CSVs
else:
    # The above logic

答案 7 :(得分:0)

使用Python 3时,可以使用codecs模块来避免出现空行。如文档中所述,文件以二进制模式打开,因此不需要更改换行符kwarg。我最近遇到了同样的问题,对我有用:

with codecs.open( csv_file,  mode='w', encoding='utf-8') as out_csv:
     csv_out_file = csv.DictWriter(out_csv)

答案 8 :(得分:0)

使用下面定义的方法将数据写入CSV文件。

open('outputFile.csv', 'a',newline='')

只需在newline=''方法内添加一个额外的open参数:

def writePhoneSpecsToCSV():
    rowData=["field1", "field2"]
    with open('outputFile.csv', 'a',newline='') as csv_file:
        writer = csv.writer(csv_file)
        writer.writerow(rowData)

这将写入CSV行,而不会创建其他行!

答案 9 :(得分:0)

with open(destPath+'\\'+csvXML, 'a+') as csvFile:
    writer = csv.writer(csvFile, delimiter=';', lineterminator='\r')
    writer.writerows(xmlList)

“ lineterminator ='\ r'”允许传递到下一行,而两行之间不能有空行。