将utf-8格式的Python列表写入CSV

将utf-8格式的Python列表写入CSV,python,list,csv,utf-8,export-to-csv,Python,List,Csv,Utf 8,Export To Csv,如何将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

如何将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)
回溯(最近一次呼叫最后一次):
文件“2010rudeni priimti.py”,第263行,在
writer.writerow(mem)
文件“C:\Python27\lib\codecs.py”,第691行,写入
返回self.writer.write(数据)
写入文件“C:\Python27\lib\codecs.py”,第351行
数据,消耗=self.encode(对象,self.errors)
文件“C:\Python27\lib\encodings\utf_8_sig.py”,第82行,在encode中
返回编码(输入、错误)
文件“C:\Python27\lib\encodings\utf_8_sig.py”,第15行,编码
返回(codecs.BOM_UTF8+codecs.utf_8_编码(输入,错误)[0],len(输入))
UnicodeDecodeError:“ascii”编解码器无法解码位置11:序号不在范围(128)中的字节0xc4
按任意键继续

我的错误是什么?

2.x中的模块不读/写Unicode,它读/写字节(并假设它们是ASCII兼容的,但这不是UTF-8的问题)

因此,当您给它一个
codecs
Unicode文件进行写入时,它会传递一个
str
,而不是
Unicode
。当
codecs
尝试
encode
将其编码为UTF-8时,它必须首先
将其解码为Unicode,使用默认编码,即ASCII,但失败。因此,这个错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 11: ordinal not in range(128)
文档中解释了解决方案,其中包含一个包装器,可以为您处理所有事情。将
UnicodeWriter
与普通二进制文件一起使用,而不是使用
编解码器
文件


作为替代方案,PyPI上有几个不同的包,它们封装了
csv
模块,直接在
unicode
中处理,而不是
str
,如

作为一个更激进的替代方案,Python3.x的
csv
模块一开始就没有这个问题(3.x也没有下一个问题)

另一种黑客的选择是假装整个世界都是UTF-8。毕竟,您的源代码和输出都是UTF-8,而
csv
模块只关心少量ASCII兼容字符(换行符、逗号、引号和反斜杠)。所以你可以完全跳过解码和编码,一切都会正常的。这里明显的缺点是,如果出现任何错误,您将得到一个充满垃圾的文件,而不是调试错误


代码中还有另外两个问题,
UnicodeWriter
unicodesv
都不能神奇地解决(尽管Python 3可以解决第一个问题)

首先,您实际上并没有首先给出
csv
模块Unicode。源数据中的列是纯旧的
str
文本,如
“?ž”
。您不能将其编码为UTF-8,或者更确切地说,您可以,但必须首先将其自动解码为ascii,这将再次导致相同的错误。使用Unicode文本,如
u“?ž”
,以避免这种情况(或者,如果您愿意,可以从源代码显式地
解码
,但这有点愚蠢)


其次,您没有在源代码中指定,但使用了非ASCII字符。从技术上讲,这在Python2.7中是非法的。实际上,我很确定它会给你一个警告,但会把你的来源当作拉丁语-1。这是不好的,因为您显然没有使用Latin-1编辑器(您不能将
ž
放在Latin-1文本文件中,因为没有这样的字符)。如果您将文件保存为UTF-8,然后告诉Python将其解释为拉丁语-1,那么您将得到
而不是
问žžž
,以及类似的mojibake。

作为旁注,您还没有为源代码指定编码,这意味着Python将把它解释为拉丁语-1(可能有警告,但我想你要么没有看到,要么忽略了?)…但您显然是将其编辑为不同的内容,因为拉丁语-1中没有
ž
字符。因此,即使您解决了当前的问题,您也只需将mojibake写入文件。例如,如果您使用UTF-8编辑器,第一个字符串将以
žžÅ
字符集=“$(file-bi“$i”| awk-F”结尾=“{print$2}”,如果[“$CHARSET”!=utf-8];那么iconv-f“$CHARSET”-t utf8“$i”-o outfile fi
@abamert,我尝试了该代码,但它不起作用。如果您不介意,我将感谢您的任何评论。