将 utf-8 格式的 Python 列表写入 CSV
Posted
技术标签:
【中文标题】将 utf-8 格式的 Python 列表写入 CSV【英文标题】:Writing utf-8 formated Python lists to CSV 【发布时间】:2014-02-03 07:01:09 【问题描述】:如何将 utf-8 字符写入 csv 文件?
我的数据和代码:
# -*- coding: utf-8 -*-
l1 = ["žžž", "ččč"]
l2 = ["žžž", "ččč"]
thelist = [l1, l2]
import csv
import codecs
with codecs.open('test', 'w', "utf-8-sig") as f:
writer = csv.writer(f)
for x in thelist:
print x
for mem in x:
writer.writerow(mem)
错误信息:
Traceback (most recent call last):
File "2010rudeni priimti.py", line 263, in <module>
writer.writerow(mem)
File "C:\Python27\lib\codecs.py", line 691, in write
return self.writer.write(data)
File "C:\Python27\lib\codecs.py", line 351, in write
data, consumed = self.encode(object, self.errors)
File "C:\Python27\lib\encodings\utf_8_sig.py", line 82, in encode
return encode(input, errors)
File "C:\Python27\lib\encodings\utf_8_sig.py", line 15, in encode
return (codecs.BOM_UTF8 + codecs.utf_8_encode(input, errors)[0], len(input))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 11: ordinal not in range(128)
按任意键继续。 . .
我的错误是什么?
【问题讨论】:
附带说明,您没有为源代码指定编码,这意味着 Python 会将其解释为 Latin-1(可能带有警告,但我猜您要么没有看到或忽略它?)...但您显然将其编辑为不同的东西,因为 is 在 Latin-1 中没有ž
字符。因此,即使您解决了当前问题,您也只需将 mojibake 写入文件。例如,如果您使用的是 UTF-8 编辑器,则第一个字符串将以 žžž
结尾。
CHARSET="$(file -bi "$i"|awk -F "=" 'print $2')" if [ "$CHARSET" != utf-8 ]; then iconv -f "$CHARSET" -t utf8 "$i" -o outfile fi
【参考方案1】:
2.x 中的 csv
模块不读/写 Unicode,它读/写字节(并假设它们是 ASCII 兼容的,但这不是 UTF-8 的问题)。
所以,当你给它一个codecs
Unicode 文件来写入时,它会传递一个str
而不是unicode
。当codecs
尝试将encode
转换为UTF-8 时,它必须首先将decode
转换为Unicode,它使用您的默认编码,即ASCII,但失败了。因此出现此错误:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 11: ordinal not in range(128)
解决方案在文档中进行了解释,Examples 中有一个包装器,可以为您处理所有事情。将UnicodeWriter
与纯二进制文件一起使用,而不是使用codecs
文件。
作为替代方案,PyPI 上有几个不同的包,它们封装了 csv
模块以直接处理 unicode
而不是 str
,例如 unicodecsv
。
作为更激进的替代方案,Python 3.x 的 csv
模块一开始就没有这个问题(而 3.x 也没有下一个问题)。
很多黑客的替代方法是假装整个世界都是 UTF-8。毕竟,您的源代码和输出都是 UTF-8 格式,而 csv
模块只关心少数字符(换行符、逗号、可能是引号和反斜杠)与 ASCII 兼容。所以你可以完全跳过解码和编码,一切都会奏效。这里明显的缺点是,如果你有任何错误,而不是调试错误,你会得到一个充满垃圾的文件。
您的代码还有另外两个问题,UnicodeWriter
或 unicodecsv
都不能神奇地修复(尽管 Python 3 可以修复第一个)。
首先,您实际上并没有提供 csv
模块 Unicode。源数据中的列是普通的旧 str
文字,例如 "žžž"
。您不能将其编码为 UTF-8,或者更确切地说,您可以,但只能首先将其自动解码为 ascii,这只会再次导致相同的错误。使用 Unicode 文字,例如 u"žžž"
,来避免这种情况(或者,如果您愿意,可以在源编码中明确地使用 decode
……但这有点傻)。
其次,您没有在源代码中指定 encoding declaration,但您使用了非 ASCII 字符。从技术上讲,这在 Python 2.7 中是非法的。实际上,我很确定它会给您一个警告,但随后会将您的来源视为 Latin-1。这很糟糕,因为您显然没有使用 Latin-1 编辑器(您不能将 ž
放在 Latin-1 文本文件中,因为没有这样的字符)。如果您将文件保存为 UTF-8,然后告诉 Python 将其解释为 Latin-1,您最终会得到 žžž
而不是 žžž
,以及类似的 mojibake。
【讨论】:
@abamert,我尝试了代码,但它不起作用。如果您不介意查看***.com/questions/49121728/…,我将不胜感激您拥有的任何 cmets。以上是关于将 utf-8 格式的 Python 列表写入 CSV的主要内容,如果未能解决你的问题,请参考以下文章
使用 FileWriter (Java) 以 UTF-8 格式写入文件?