модуль python, такой как csv-DictReader с полной поддержкой utf8 - PullRequest
1 голос
/ 30 марта 2011

Мне нужно импортировать данные из CSV в моем проекте, и мне нужен объект, такой как DictReader, но с полной поддержкой utf8, кто-нибудь знает модуль или приложение с этим?

Ответы [ 2 ]

3 голосов
/ 30 марта 2011

Ваши данные НЕ кодируются в UTF-8. Он (в основном) кодируется в cp1252 . Данные, кажется, включают испанские имена. Наиболее распространенным не-ASCII-символом является '\ xd1` (то есть латинская заглавная буква N с тильдой) - это символ, вызвавший исключение.

Один из не-ASCII символов в файле - это \ x8d. Это не в cp1252. Появляется там, где буква А должна появиться в названии VASQUEZ. Из других, '\ x94' (двойная кавычка в cp1252) появляется в середине имени. Остальные могут также представлять ошибки.

Я предлагаю вам запустить этот небольшой фрагмент кода, чтобы напечатать строки с подозрительными символами в них:

for lino, line in enumerate(open('sampleresults.csv')):
    if any(c in line for c in '\x8d\x94\xc1\xcf\xd3'): print "%d %r\n" % (lino+1, line)

и исправьте данные.

Затем вам нужен CSV DictReader с поддержкой full и обобщенного декодирования. Полный означает расшифровку названий полей или ключей, а также данных. Обобщенный означает отсутствие жесткого кодирования кодировки.

импорт CSV

def UnicodeDictReader(str_data, encoding, **kwargs):
    csv_reader = csv.DictReader(str_data, **kwargs)
    # Decode the keys once
    keymap = dict((k, k.decode(encoding)) for k in csv_reader.fieldnames)
    for row in csv_reader:
        yield dict((keymap[k], v.decode(encoding)) for k, v in row.iteritems())

dozedata = ['\xd1,\xff', '\xd2,\xfe', '3,4']
print list(UnicodeDictReader(dozedata, 'cp1252'))

Выход:

[{u'\xd1': u'\xd2', u'\xff': u'\xfe'}, {u'\xd1': u'3', u'\xff': u'4'}]

и вот что вы получаете с вашим примером файла (только первая строка данных, Python 2.7.1, Windows 7):

>>> import csv
>>> from pprint import pprint as pp
>>> def UnicodeDictReader(str_data, encoding, **kwargs):
...     csv_reader = csv.DictReader(str_data, **kwargs)
...     # Decode the keys once
...     keymap = dict((k, k.decode(encoding)) for k in csv_reader.fieldnames)
...     for row in csv_reader:
...         yield dict((keymap[k], v.decode(encoding)) for k, v in row.iteritems())
...
>>> f = open('sampleresults.csv', 'rb')
>>> drdr = UnicodeDictReader(f, 'cp1252')
>>> pp(drdr.next())
{u'APELLIDO': u'=== family names redacted ===',
 u'CATEGORIA': u'ABIERTA',
 u'CEDULA': u'10000640',
 u'DELAY': u' 0:20',
 u'EDAD': u'25',
 u'EMAIL': u'mimail640',
 u'NO.': u'640',
 u'NOMBRE': u'=== given names redacted ===',
 u'POSICION CATEGORIA': u'1',
 u'POSICION CATEGORIA EN KM.5': u'11',
 u'POSICION GENERAL CHIP': u'1',
 u'POSICION GENERAL EN KM.5': u'34',
 u'POSICION GENERAL GUN': u'1',
 u'POSICION GENERO': u'1',
 u'PRIMEROS 5KM.': u'0:32:55',
 u'PROMEDIO/KM.': u' 5:44',
 u'SEGUNDOS KM.': u'0:24:05',
 u'SEX': u'M',
 u'TIEMPO CHIP': u'0:56:59',
 u'TIEMPO GUN': u'0:57:19'}
>>>
0 голосов
/ 30 марта 2011

В ответ на этот пост сказал:

def UnicodeDictReader(utf8_data, **kwargs):
    csv_reader = csv.DictReader(utf8_data, **kwargs)
    for row in csv_reader:
        yield dict([(key, unicode(value, 'utf-8')) for key, value in row.iteritems()])

Вы можете увидеть ниже мой пример кода.Я использую ваш CSV-файл (см. Комментарии).

import csv

def UnicodeDictReader(utf8_data, **kwargs):
    csv_reader = csv.DictReader(utf8_data, **kwargs)
    for row in csv_reader:
        yield dict([(key, unicode(value, 'utf-8')) for key, value in row.iteritems()])

f = open('sampleresults.csv', 'r')
a = UnicodeDictReader(f)
for i in a:
    if i['NOMBRE'] == 'GUIDO ALEJANDRO':
        print i['APELLIDO']

Ouput:

MUÑOZ RENGIFO

Вы видите, что 'С' правильно закодировано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...