AFAIK,Python(v2.6)csv模块默认无法处理unicode数据,对吗?在Python文档中,有一个关于如何从UTF-8编码文件中读取的example。但是此示例仅将CSV行作为列表返回。
我希望按名称访问行列,因为它由csv.DictReader
完成,但使用UTF-8编码的CSV输入文件。
有谁能告诉我如何以有效的方式做到这一点?我将不得不以100的MByte格式处理CSV文件。
答案 0 :(得分:50)
我自己想出了一个答案:
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()}
注意:这已经更新,因此根据评论中的建议解码密钥
答案 1 :(得分:2)
对我来说,关键不是操纵csv DictReader args,而是操纵文件打开器本身。这可以达到目的:
with open(filepath, mode="r", encoding="utf-8-sig") as csv_file:
csv_reader = csv.DictReader(csv_file)
不需要特殊的课程。现在,无论有没有BOM,我都可以打开文件而不会崩溃。
答案 2 :(得分:0)
首先,使用2.6 version of the documentation。它可以针对每个版本进行更改。它清楚地表明它不支持Unicode,但它确实支持UTF-8。 Technically,这些不是一回事。正如文档所说:
csv模块不直接支持读取和写入Unicode,但除了ASCII NUL字符的某些问题外,它还是8位清除。因此,只要您避免使用像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]
答案 3 :(得分:0)
基于分类的@LMatter回答方法,通过这种方法,您仍然可以获得DictReader的所有好处,例如获取字段名并获取行号以及它处理UTF-8
import csv
class UnicodeDictReader(csv.DictReader, object):
def next(self):
row = super(UnicodeDictReader, self).next()
return {unicode(key, 'utf-8'): unicode(value, 'utf-8') for key, value in row.iteritems()}
答案 4 :(得分:0)
csvw
package还具有其他功能(用于Web上的元数据丰富的CSV),但是它定义了一个UnicodeDictReader
类,围绕其UnicodeReader
类,该类实际上是正是这样:
class UnicodeReader(Iterator):
"""Read Unicode data from a csv file."""
[…]
def _next_row(self):
self.lineno += 1
return [
s if isinstance(s, text_type) else s.decode(self._reader_encoding)
for s in next(self.reader)]
它确实使我失望了几次,但是csvw.UnicodeDictReader
确实确实需要在with
块中使用,否则会中断。除此之外,该模块非常通用,并且与py2和py3都兼容。
答案 5 :(得分:0)
答案没有DictWriter
方法,因此这是更新的类:
class DictUnicodeWriter(object):
def __init__(self, f, fieldnames, dialect=csv.excel, encoding="utf-8", **kwds):
self.fieldnames = fieldnames # list of keys for the dict
# Redirect output to a queue
self.queue = cStringIO.StringIO()
self.writer = csv.DictWriter(self.queue, fieldnames, dialect=dialect, **kwds)
self.stream = f
self.encoder = codecs.getincrementalencoder(encoding)()
def writerow(self, row):
self.writer.writerow({k: v.encode("utf-8") for k, v in row.items()})
# Fetch UTF-8 output from the queue ...
data = self.queue.getvalue()
data = data.decode("utf-8")
# ... and reencode it into the target encoding
data = self.encoder.encode(data)
# write to the target stream
self.stream.write(data)
# empty queue
self.queue.truncate(0)
def writerows(self, rows):
for row in rows:
self.writerow(row)
def writeheader(self):
header = dict(zip(self.fieldnames, self.fieldnames))
self.writerow(header)
答案 6 :(得分:0)
使用unicodecsv软件包很容易。
# pip install unicodecsv
import unicodecsv as csv
with open('your_file.csv') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
print(row)