Python: UnicodeEncodeError: 'ascii' 编码无法在位置 34-39 编码字符: 值超出范围(128)
我有一份Twitter日志的数据,我需要对这个文件进行排序,以显示每个用户转发的推文排名。
这是我写的代码。
import codecs
with codecs.open('hoge_qdata.tsv', 'r', 'utf-8') as tweets:
tweet_list = tweets.readlines()
tweet_list.pop(0)
facul={}
for t in tweet_list:
t = t.split('\t')
t[-2] = int(t[-2])
if t[-2] <= 0:
continue
if not t[0] in facul:
facul[t[0]] = []
facul[t[0]].append(t)
def cmp_retweet(a,b):
if a[-2] < b[-2]:
return 1
if a[-2] > b[-2]:
return -1
return 0
for f in sorted(facul.keys()):
facul[f].sort(cmp=cmp_retweet)
print ('[%s]' %(f))
for t in facul[f][:5]:
print ('%d:%s:%s' % (t[-2], t[2], t[-1].strip())
但是我遇到了一个错误,提示:
print '%d:%s:%s' %(t[-2], t[2], t[-1].strip())
UnicodeEncodeError: 'ascii' codec can't encode characters in position
34-39: ordinal not in range(128)
看起来日文字符无法被解码。我该怎么解决这个问题?我试着用 sys.setdefaultencoding("utf-8")
,但又出现了一个错误:
sys.setdefaultencoding("utf-8")
AttributeError: 'module' object has no attribute 'setdefaultencoding'
这是我尝试的方式:
import codecs
import sys
sys.setdefaultencoding("utf-8")
with codecs.open('hoge_qdata.tsv', 'r', 'utf-8') as tweets:
tweet_list = tweets.readlines()
顺便说一下,我使用的是Python 2.7.5版本。
2 个回答
你发现的基本问题是,ASCII编码无法表示很多Unicode字符。
所以你需要选择一种处理方式:
- 不显示非ASCII字符
- 将非ASCII字符显示为其他类型的表示方式
第一种选择的代码看起来像这样:
for t in facul[f][:5]:
print ('%d:%s:%s' % (
t[-2],
t[2].encode('ascii', errors='ignore'),
t[-1].encode('ascii', errors='ignore').strip()
))
而第二种选择则会把ignore
替换成像replace
、xmlcharrefreplace
或者backslashreplace
这样的选项。
这里有一个参考链接。
这个错误信息给了你两个提示:首先,问题出在这条语句上。
print '%d:%s:%s' %(t[-2], t[2], t[-1].strip())
其次,问题和一个叫做encode
的操作有关。如果你不太明白“编码”是什么意思,现在是时候去看看Unicode HOWTO这篇文章了,里面有关于Python 2.7的相关内容。
看起来你的列表t[]
里包含了Unicode字符串。而print()
语句输出的是字节字符串。将Unicode字符串转换成字节字符串的过程叫做编码。因为你没有指定编码方式,Python就默认使用了一种编码方式。它使用的是ascii
编码,但这个编码无法处理带重音的字符或非拉丁字符。
你可以试着把print()
语句拆成两部分。首先,把Unicode的t[]
值放入一个Unicode格式的字符串中。注意要使用u''
的语法。然后,把这个Unicode字符串编码成UTF格式并打印出来。
s = u'%d:%s:%s' %(t[-2], t[2], t[-1].strip())
print s.encode('utf8')
(我没有测试过你代码的这个改动。如果不行,请告诉我。)
我觉得sys.setdefaultencoding()
可能并不是问题的关键,但我对你的环境不太了解。
顺便说一下,你上面写的语句有括号不平衡的问题。你在粘贴代码时是不是漏掉了一个右括号?
print ('%d:%s:%s' %(t[-2], t[2], t[-1].strip())