Пакет Python CSV - проблема с модулем DictReader - PullRequest
0 голосов
/ 27 сентября 2019

У меня возникла любопытная проблема с пакетом csv в Python 3.7.

Я импортирую файл 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 fieldnames`.

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.inputfile - это pathlib.Path объект)

Я не заметил этого длядолгое время, потому что я не использовал первый столбец (с заголовком #) - я некоторое время счастливо разбирался с остальными столбцами на нескольких файлах.

Если я смотрю прямо наcsv, похоже, нет никаких проблем:

```csv


Вопросы:

Кто-нибудь знает, в чем проблемаявляется?Могу ли я попытаться исправить проблему с импортом?

Если исправления нет, есть ли лучший способ разобрать мусор?Я понимаю, что это может проясниться в будущем, но я думаю, что разделение все равно будет работать даже с простыми двойными кавычками (заголовок должен быть вторым элементом в разделении, верно?).Есть ли лучшее решение?

1 Ответ

1 голос
/ 27 сентября 2019

Похоже, ваш CSV-файл закодирован как utf-8-sig - версия utf-8, используемая некоторыми приложениями Windows, но она декодируется как cp1252 - другаяШироко используемое кодирование в Windows.

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

Символы «мусора», предшествующие заголовку, являются меткой порядка байтов, которую utf-8-sig использует, чтобы сообщить приложениям Windows, что файл имеет кодировку . как 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
    ...

Если - как представляется вероятным - кодировка входных файлов может отличаться, значение encoding (или лучшая догадка) должен быть определен с помощью инструмента, подобного chardet , как используется в комментариях.

...