首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python: Unicode字典

Python: Unicode字典
EN

Stack Overflow用户
提问于 2014-12-10 05:56:45
回答 1查看 393关注 0票数 0

我正在尝试将一个选项卡分隔的utf-8文件读入Python字典,然后检查用户的输入是否以字典键的形式出现。

这就是我到目前为止尝试过的。

代码语言:javascript
复制
#!/usr/bin/env python
# -*- coding: utf-8 -*- 

def create_idiom_dic(idiom_file):    
  newDict= {}
  with io.open(idiom_file, 'r', encoding='utf-8') as f :
    for line in f:
        line = line.strip()
        if line:
            splitLine = line.split("\t")
            newDict[splitLine[0]] = ",".join(splitLine[1:])
  return newDict

def check_idioms(text, lang):
  si_idioms = create_idiom_dic("si.txt")
  ta_idioms = create_idiom_dic("ta.txt")    
  if lang == "si":
    if text in si_idioms:
        print si_idioms[text] 
  else:
        print si_idioms[text]

问题是,当给定正确的键时,我无法获得匹配的值。假设我将输入文本作为

代码语言:javascript
复制
print ta_idioms[text] 

其中的文本是“அவர்சிவலோகபதவி”。这就产生了一个关键错误:

代码语言:javascript
复制
KeyError: '\xe0\xae\x85\xe0\xae\xb5\xe0\xae\xb0\xe0\xaf\x8d \xe0\xae\x9a\xe0\xae\xbf\xe0\xae\xb5\xe0\xae\xb2\xe0\xaf\x8b\xe0\xae\x95 \xe0\xae\xaa\xe0\xae\xa4\xe0\xae\xb5\xe0\xae\xbf.' 

但是,如果我尝试打印。

代码语言:javascript
复制
print ta_idioms["அவர் சிவலோக பதவி."]

这给出了正确的结果。

-更新--

经过更多的努力,我发现错误是由于我传入的输入文本的编码造成的。输入最初是从我打开的文本文件中读取的,并按下面的方式调用check_idiom函数。我试图解码文本,但它给出了一个编码错误。

代码语言:javascript
复制
if __name__ == '__main__':
  with io.open(input_file, 'r', encoding='utf-8') as f:
    for line in f:
        text = line.strip().decode('utf-8')
        print text  
        #check_idioms(text, lang)

然后返回错误:

代码语言:javascript
复制
text = line.strip().decode('utf-8')
File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not  in range(128)

应该做些什么来解决这个问题?

-更新2-文件的十六进制转储是:

代码语言:javascript
复制
0000000   �   � 221   �   � 232       �   � 234   �   � 204   �   � 232
0000010       �   � 234   �   � 231   �   �   �   �   � 222            
000001e
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-10 06:21:58

在Unicode中有多种表示相同文本的方法。为了将Unicode文本作为键使用,需要将其规范化。Unicode标准定义了四种不同的规范化形式,但对于这种特殊情况,选择哪一种并不重要,只要您始终使用它。

代码语言:javascript
复制
from unicodedata import normalize

# ...
    newDict[normalize('NFKC', splitLine[0])] = ",".join(splitLine[1:])

# ...
print ta_idioms[normalize('NFKC',u"அவர் சிவலோக பதவி.")]

有关(简要)文档,请参见unicodedata等价性

如果变量text不是正确的Unicode字符串,则需要在将其用作键之前对其进行转换。我猜在这个案子里你要找的是

代码语言:javascript
复制
print ta_idioms[normalize('NFKC', text.decode('utf-8'))]

..。或者更好的是,不管是什么初始化的text,首先都应该正确地解码它。

错误消息中字符串的第一个字节似乎表示U+0B85的UTF-8编码,这意味着您在读取文件时没有像在示例中显示的那样完成解码;或者输入文件可能是错误的,并且包含了双编码的文本。

您可能需要考虑通过为ta_idioms创建一个特定的类来封装Unicode规范化,该类提供了负责处理这些细节的访问器函数,因此使用它的代码不必这样做。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27394186

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档