Python: UnicodeEncodeError: 'ascii' 编码无法在位置 34-39 编码字符: 值超出范围(128)

0 投票
2 回答
3345 浏览
提问于 2025-04-18 12:34

我有一份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 个回答

0

你发现的基本问题是,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替换成像replacexmlcharrefreplace或者backslashreplace这样的选项。

这里有一个参考链接

0

这个错误信息给了你两个提示:首先,问题出在这条语句上。

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())

撰写回答