Python使用UTF-8数据的CSV DictReader
据我所知,Python(版本2.6)的csv模块默认不能处理unicode数据,对吧?在Python的文档里有一个示例,讲的是如何从一个UTF-8编码的文件中读取数据。但是这个示例只把CSV的每一行返回为一个列表。
我想像使用csv.DictReader
那样,通过列名来访问行的各个列,但我需要处理的是UTF-8编码的CSV输入文件。
有没有人能告诉我怎么高效地做到这一点?因为我需要处理的CSV文件可能有几百兆字节那么大。
7 个回答
1
首先,建议使用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]
39
对我来说,关键不在于调整csv的DictReader参数,而是在于打开文件的方式。这样做就解决了问题:
with open(filepath, mode="r", encoding="utf-8-sig") as csv_file:
csv_reader = csv.DictReader(csv_file)
不需要任何特别的类。现在我可以顺利打开带有或不带有BOM的文件,而不会出现崩溃的情况。
55
我自己想出了一个答案:
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()}
注意:这个已经更新过了,所以根据评论里的建议,键值现在是解码的