Python CSV软件包-DictReader模块出现问题

时间:2019-09-27 03:16:44

标签: python python-3.x csv utf-8 python-unicode

我对Python 3.7中的csv包有一个奇怪的问题。

我正在导入一个csv文件,并且能够按预期访问所有文件,但有一个例外-头行(存储在“ fieldnames”对象中)显示的第一列标题(字段名中的第一项)格式错误

此第一个字段始终具有以下格式:'xxx"header"'

其中:

  1. xxx是看上去总是一样的垃圾字符
  2. header是正确的标题文本

从调试窗口中查看table <csv.DictReader>对象的以下屏幕截图: enter image description here

打开文件的代码如下。我添加了headers[0] = table.fieldnames[0].split('"')[1] in order to extract the correct header and place it back into字段名`。

import csv

  with self.inputfile.open() as self.inputfid:
    table = csv.DictReader(self.inputfid, delimiter=',')
    headers = table.fieldnames
    headers[0] = table.fieldnames[0].split('"')[1]

注意: self.inputfilepathlib.Path对象)

我很长一段时间都没有注意到这一点,因为我没有使用第一列(带有#标题)-我很高兴地在多个文件上与其余列进行了一段时间的解析。

如果我直接看csv,似乎没有任何问题:

```csv


问题:

有人知道这个问题是什么吗?我有什么可以尝试纠正导入问题的?

如果没有修复程序,是否有更好的方法来解析垃圾?我意识到将来可能会解决此问题,但是我认为即使仅使用双引号也可以使拆分仍然有效(标头仍应是拆分中的第二项,对吗?)。有更好的解决方案吗?

1 个答案:

答案 0 :(得分:1)

您的csv文件似乎被编码为 utf-8-sig -一些Windows应用程序使用的utf-8版本,但已被解码为 cp1252 -Windows上的另一种常用编码。

>>> print('"#"'.encode('utf-8-sig').decode('cp1252'))
"#"

标头前面的“垃圾”字符是utf-8-sig用来告诉Windows应用程序文件encoded为utf-8的字节顺序标记,而不是历史上更常见的文件之一8位编码。

为避免产生“垃圾”,请在打开文件时将utf-8-sig指定为编码。

问题中的代码可以修改为这样:

import csv

encoding = 'utf-8-sig'
with self.inputfile.open(encoding=encoding, newline='') as self.inputfid:
    table = csv.DictReader(self.inputfid, delimiter=',')
    headers = table.fieldnames
    ...

如果(似乎很可能)输入文件的编码可能不同,则必须使用chardet之类的工具来确定encoding的值(或最佳猜测),如注释中所用。