Подтвердить что ты не робот

Python CSV DictReader с данными UTF-8

AFAIK, модуль csv Python (v2.6) не может обрабатывать данные Unicode по умолчанию, правильно? В документах Python есть example о том, как читать из кодированного файла UTF-8. Но этот пример возвращает строки CSV в виде списка. Я хотел бы получить доступ к столбцам строк по имени, как это делается с помощью csv.DictReader, но с входным файлом CSV с кодировкой UTF-8.

Может ли кто-нибудь сказать мне, как сделать это эффективным способом? Мне придется обрабатывать CSV файлы в 100 размерах MByte.

4b9b3361

Ответ 1

Я сам пришел с ответом:

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

Примечание. Это обновление было обновлено, поэтому ключи декодируются в соответствии с предложением в комментариях

Ответ 2

Прежде всего, используйте 2.6 версию документации. Он может меняться для каждой версии. В нем четко сказано, что он не поддерживает Unicode, но поддерживает UTF-8. Технически, это не одно и то же. Как говорят документы:

Модуль csv напрямую не поддерживает чтение и запись Unicode, но он имеет 8-битную чистоту для некоторых проблем с символами ASCII NUL. Таким образом, вы можете писать функции или классы, которые обрабатывают кодировку и декодирование для вас, если вы избегаете кодировок, таких как UTF-16, которые используют NUL. Рекомендуется использовать UTF-8.

В приведенном ниже примере (из документации) показано, как создать две функции, которые правильно читают текст как UTF-8 как CSV. Вы должны знать, что csv.reader() всегда возвращает объект DictReader.

import csv

def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
    # csv.py doesn't do Unicode; encode temporarily as UTF-8:
    csv_reader = csv.DictReader(utf_8_encoder(unicode_csv_data),
                            dialect=dialect, **kwargs)
    for row in csv_reader:
        # decode UTF-8 back to Unicode, cell by cell:
        yield [unicode(cell, 'utf-8') for cell in row]