像csv-DictReader一样的python模块,支持完整的utf8

时间:2011-03-29 20:41:06

标签: python csv utf-8

我需要在我的项目中从csv导入数据,我需要一个像DictReader这样的对象,但是有了完整的utf8支持,任何人都知道这个模块或应用程序吗?

2 个答案:

答案 0 :(得分:3)

您的数据未以UTF-8编码。它(大部分)以cp1252 编码。数据似乎包括西班牙名字。最普遍的非ASCII字符为“\ xd1`(即音符的大写字母N与波浪号) - 这是导致异常的字符

文件中的一个非ASCII字符是'\ x8d'。它不在cp1252中。它出现在字母A应出现在名称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。完全意味着解码字段名称dict键以及数据。通用意味着没有编码的硬编码。

导入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'}
>>>

答案 1 :(得分:0)

正如this post的答案所说:

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']

输出继电器:

MUÑOZ RENGIFO

您可以看到'Ñ'编码正确。