UnicodeEncodeError:' ascii'编解码器不能使用writerow和map编码字符错误

时间:2016-07-10 21:14:55

标签: python csv unicode encoding utf-8

在Python 2.7和Ubuntu 14.04中,我试图写一个csv文件:

csv_w.writerow( map( lambda x: flatdata.get( x, "" ), columns ))

这给了我臭名昭着的

UnicodeEncodeError: 'ascii' codec can't encode character u'\u265b' in position 19: ordinal not in range(128)

错误。

这里通常的建议是使用unicode(x).encode("utf-8") 我在get:

中尝试了这个以及.encode("utf-8")这两个参数
csv_w.writerow( map( lambda x: flatdata.get( unicode(x).encode("utf-8"), unicode("").encode("utf-8") ), columns ))

但我仍然得到同样的错误。

任何帮助都非常感谢摆脱错误。 (我想unicode("").encode("utf-8")很笨拙,但我还是个新手。)

编辑: 我的完整计划是:

#!/usr/bin/env python
import json
import csv
import fileinput
import sys
import glob
import os
def flattenjson( b, delim ):
val = {}
for i in b.keys():
    if isinstance( b[i], dict ):
        get = flattenjson( b[i], delim )
        for j in get.keys():
            val[ i + delim + j ] = get[j]
    else:
        val[i] = b[i]
return val
def createcolumnheadings(cols):
    #create column headings
    print ('a', cols)
    columns = cols.keys()
    columns = list( set( columns ) )
    print('b', columns)
    return columns
doOnce=True
out_file= open( 'Excel.csv', 'wb' )
csv_w = csv.writer( out_file, delimiter="\t"  )
print sys.argv, os.getcwd()
os.chdir(sys.argv[1])
for line in fileinput.input(glob.glob("*.txt")):
    print('filename:', fileinput.filename(),'line  #:',fileinput.filelineno(),'line:', line)
    data = json.loads(line)
    flatdata = flattenjson(data, "__")
    if doOnce:
        columns=createcolumnheadings(flatdata)     
        print('c', columns)
        csv_w.writerow(columns)                
        doOnce=False
    csv_w.writerow( map( lambda x: flatdata.get( unicode(x).encode("utf-8"), unicode("").encode("utf-8") ), columns ))

引发错误UnicodeEncodeError: 'ascii' codec can't encode character u'\u2022' in position 14: ordinal not in range(128)的已修改的单条推文:可用here

按照Alistair的建议解决方案我安装了unicodescv。 步骤是: 从here

下载邮政编码

安装它:sudo pip install /path/to/zipfile/python-unicodecsv-master.zip

import unicodecsv as csv
csv_w = csv.writer(f, encoding='utf-8')
csv_w.writerow(flatdata.get(x, u'') for x in columns)

2 个答案:

答案 0 :(得分:1)

在没有看到您的数据的情况下,您的数据似乎包含Unicode数据类型(有关Unicodestr类型的简要介绍,请参阅How to fix: "UnicodeDecodeError: 'ascii' codec can't decode byte"

您对encode的解决方案很容易出错 - 任何带有非ascii编码的str都会在您unicode()时抛出错误(请参阅前面的链接以获取解释)。

在写入CSV之前,您应该将所有数据转换为Unicode类型。由于Python 2.7的CSV模块已损坏,您需要使用drop in replacement:https://github.com/jdunck/python-unicodecsv

您可能还希望将map分成单独的声明以避免混淆。确保提供完整的堆栈跟踪和代码示例。

答案 1 :(得分:1)

csv_w.writerow( map( lambda x: flatdata.get( unicode(x).encode("utf-8"), unicode("").encode("utf-8") ), columns ))

You've encoded the parameters passed to flatdata.get(), ie the dict key. But the unicode characters aren't in the key, they're in the value. You should encode the value returned by get():

csv_w.writerow([flatdata.get(x, u'').encode('utf-8') for x in columns])