遍历Unicode字符串并与Python词典中的Unicode比较

9 投票
1 回答
7404 浏览
提问于 2025-04-16 23:04


我有两个Python字典,里面存的是关于日语单词和字符的信息:

  1. vocabDic:这个字典里存的是词汇,键是单词,值是一个包含该单词信息的字典。
  2. kanjiDic:这个字典里存的是汉字(单个日语字符),键是汉字,值是一个包含该汉字信息的字典。

    现在我想遍历vocabDic中每个单词的每个字符,并在kanji字典中查找这个字符。我的目标是创建一个CSV文件,然后可以把它导入到数据库中,作为词汇和汉字的连接表。
    我的Python版本是2.6
    我的代码如下:

    kanjiVocabJoinWriter = csv.writer(open('kanjiVocabJoin.csv', 'wb'), delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)
    kanjiVocabJoinCount = 1
    
    #loop through dictionary
    for key, val in vocabDic.iteritems():
        if val['lang'] is 'jpn': # only check japanese words
            vocab = val['text']
            print vocab
            # loop through vocab string
            for v in vocab:
                 test = kanjiDic.get(v)
                 print v
                 print test
                 if test is not None:
                    print str(kanjiVocabJoinCount)+','+str(test['id'])+','+str(val['id'])
                    kanjiVocabJoinWriter([str(kanjiVocabJoinCount),str(test['id']),str(val['id'])])
                    kanjiVocabJoinCount = kanjiVocabJoinCount+1
    

如果我在命令行打印这些变量,我得到的结果是:
vocab:正常,打印出日文
v(在for循环中vocab的一个字符):�
test(在kanjiDic中查找的字符):None

在我看来,for循环搞乱了编码。
我尝试了各种函数(解码、编码等),但到现在为止都没有成功。
有没有什么想法可以让我解决这个问题?
非常感谢任何帮助。

1 个回答

11

根据你描述的问题,听起来像是 vocab 是一个编码过的 str 对象,而不是 unicode 对象。

为了更具体一点,假设 vocab 等于 u'債務の天井',并且它是用 utf-8 编码的:

In [42]: v=u'債務の天井'
In [43]: vocab=v.encode('utf-8')   # val['text']
Out[43]: '\xe5\x82\xb5\xe5\x8b\x99\xe3\x81\xae\xe5\xa4\xa9\xe4\xba\x95'

如果你对这个编码过的 str 对象进行循环,你会一次得到一个字节:首先是 \xe5,然后是 \x82,接着是 \xb5,等等。

但是如果你对 unicode 对象进行循环,你会一次得到一个 unicode 字符:

In [45]: for v in u'債務の天井':
   ....:     print(v)    
債
務
の
天
井

注意,第一个用 utf-8 编码的 unicode 字符是 3 个字节:

In [49]: u'債'.encode('utf-8')
Out[49]: '\xe5\x82\xb5'

这就是为什么逐字节循环并打印每个字节(例如 print \xe5)无法打印出一个可识别的字符。

所以看起来你需要解码你的 str 对象,并使用 unicode 对象。你没有提到你的 str 对象使用了什么编码。如果是 utf-8,那么你可以这样解码:

vocab=val['text'].decode('utf-8')

如果你不确定 val['text'] 是什么编码,可以把输出结果发出来:

print(repr(vocab))

也许我们可以猜出它的编码。

撰写回答