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

l--*_*''' 394 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)
Run Code Online (Sandbox Code Playgroud)

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

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

有没有办法让它没有多余的空白?

Mar*_*nen 781

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

在Python 3中,所需的语法已更改,因此请outfile使用其他参数打开newline=''.

例子:

# Python 2
with open('/pythonwork/thefile_subset11.csv', 'wb') as outfile:
    writer = csv.writer(outfile)

# Python 3
with open('/pythonwork/thefile_subset11.csv', 'w', newline='') as outfile:
    writer = csv.writer(outfile)
Run Code Online (Sandbox Code Playgroud)

文档链接

  • 无论如何,@Mark Tolonen 的回答确实解决了许多与保存标准(未使用 csv)文本文件时添加的额外行相关的问题。 (2认同)
  • 为了 2.6/2.7 和 3 之间的兼容性,您可以使用 [`io.open`](https://docs.python.org/2/library/io.html#io.open) 和 `newlines` 参数。如果您仍在使用 2.x 进行编写,那么无论如何这似乎是一个更好的选择,因为它是向前兼容的。 (2认同)
  • 知道为什么 `newline=''` 技巧在带有 StringIO 或 TemporaryFile 的 python3 中不起作用吗? (2认同)

Dav*_*dox 50

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

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

with open('/pythonwork/thefile_subset11.csv', 'w', newline='') as outfile:
Run Code Online (Sandbox Code Playgroud)


小智 16

自最初问题提出以来的十年里,许多其他答案已经过时。对于Python3,答案在文档中是正确的:

如果 csvfile 是文件对象,则应使用以下命令打开它newline=''

脚注更详细地解释了

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


Joh*_*hin 13

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

摆弄lineterminator不是解决方案.

  • 要点是(正如您所暗示的)没有标准。该 RFE 是信息性的。虽然 \r\n 在 Windows 上可能是“标准的”,但我确信 Unix 应用程序通常不会这么看。 (3认同)
  • @Dan:我用"标准"作为形容词,而不是名词,意思是"通常"或"普通".如果你想要一个(名词)标准的近似值,请阅读http://tools.ietf.org/html/rfc4180 (2认同)
  • @Dan:这是正确的 - 没有标准.脚本应该指定他们想要的lineterminator [应该被命名为ROWterminator](如果不是默认值)并且仍然使用二进制模式以防脚本在Windows上运行,否则可能会填充"lineterminator". (2认同)

Feb*_*hew 8

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

open('outputFile.csv', 'a',newline='')
Run Code Online (Sandbox Code Playgroud)

只需在方法中添加一个附加newline=''参数open

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

这将写入 CSV 行,而无需创建其他行!


Der*_*itz 7

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

如果csvfile是一个文件对象,则必须在平台上打开"b"标志,这会产生影响.

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

来自Python文档:

在Windows上,附加到模式的'b'以二进制模式打开文件,因此还有'rb','wb'和'r + b'等模式.Windows上的Python区分了文本和二进制文件; 读取或写入数据时,文本文件中的行尾字符会自动稍微改变.这种对文件数据的幕后修改适用于ASCII文本文件,但它会破坏像JPEG或EXE文件中的二进制数据.在读取和写入此类文件时要非常小心地使用二进制模式.在Unix上,将'b'附加到模式没有什么坏处,因此您可以独立于平台使用它来处理所有二进制文件.

原文:

作为csv.writer的可选参数的一部分,如果您获得额外的空行,则可能需要更改lineterminator(此处为 info ).下面的示例改编自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'])
Run Code Online (Sandbox Code Playgroud)


小智 5

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

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