Python实现针对中文排序的方法
本篇章节讲解Python实现针对中文排序的方法。分享给大家供大家参考,具体如下: Python比较字符串大小时,根据的是ord函数得到的编码值。基于它的排序函数sort可以很容易为数字和英文字母排序,因为它们在编码表中就是顺序排列的。 >> print ','< '1'<'A'<'a'<'阿' True 但要很处理中文就没那么容易了。中文通常有拼音和笔画两种排序方式,在最常用中文标准字符集GB2312中,3755个一级中文汉字是按照拼音序进行编码的,而3008个二级汉字则是按部首笔画排列, >> print '曙'< '鲑','曾'<'怡' True True 出现这样的结果是因为‘曙'和‘曾'都是常用字,而‘鲑'和‘怡'都是次常用字,但无论从笔画还是拼音来看,这两对顺序都应该反过来。后来扩充的GBK和GB18030编码为了向下兼容,都没有更改之前的汉字顺序,于是sort之后的次序就很乱了。 另一方面unicode编码的中文是按《康熙字典》的偏旁部首和笔画数来排列的,所以排序结果和GB编码又不一样。 # encoding=utf8 char=['赵','钱','孙','李','佘'] char.sort() for item in char: print item.decode('utf-8').encode('gb2312') 输出是:"佘孙李赵钱";而保存成gb2312编码后 # encoding=gb2312 char=['赵','佘'] char.sort() for item in char: print item 输出是:“李钱孙赵佘”。显然,这两个结果都不是我们想要的。那我们究竟怎样才能对中文正确排序呢? 先要弄清楚中文词典的排序规则:先按拼音排列,区分四声,拼音相同的就看笔画数目多少,笔画数也相同的再按笔顺中的具体笔划类型来区分,新华字典采用的顺序是一丨丿丶乙,也称作“天上人间”,应该没有笔划类型也完全一样的。所以中文排序不仅需要带音调的汉字拼音对照表,还需要有具体笔顺的数据。 本以为有现成的模块,试了几个都不理想。pyzh的转换代码只支持不到7千字,而且还没有音调。水木的roy的代码涵盖了2万多字符,但需要pysqlite支持......还是自立更生吧~ 我找到最全的数据是slowwind9999上传到csdn的unicode汉字编码表(点击此处本站下载。),包括全部20902个汉字的全拼、五笔、郑码、UNICODE、GBK、笔画数 部首,以及笔顺编号(拼音部分没有音调,而且个别注音有误,如 郑g,茸郑褂眯枳⒁狻#┪姨崛×似渲械谋仕呈荩钟媒炯摹笆涤煤鹤肿匆簟背绦蛑谱髁unicode汉字音调版,其中中文汉字用四声标注,319个日韩汉字没有音调以示区别,并根据汉典的数据略作修正(但仍可能存在错误)。有了这两个对照表,下面的工作就简单了。 # 建立拼音辞典 dic_py = dict() f_py = open('py.txt','r') content_py = f_py.read() lines_py = content_py.split('n') n=len(lines_py) for i in range(0,n-1): word_py,mean_py = lines_py[i].split('t',1) dic_py[word_py]=mean_py f_py.close() 笔顺字典的处理方法也完全相同,虽然文本有两万行,导入还是很快的,0.5秒左右。如果把这两个文件合并起来统一处理,应该可以更快。 # 辞典查找函数 def searchdict(dic,uchar): if isinstance(uchar,str): uchar = unicode(uchar,'utf-8') if uchar >= u'u4e00' and uchar < = u'u9fa5': value=dic.get(uchar.encode('utf-8')) if value == None: value = '*' else: value = uchar return value 查找中文,一律转为UTF8字符串,汉字外的其他字符不做处理,原样输出。如果需要声母,只输出拼音的第一个字符就是了。只要资料准确,比较起来就很轻松了。数字在字母之前,爱(ai4)便会比昂(ang2)靠前,而笔顺值的位数代表了笔画数,数值对应笔划权重,直接比较数字大小就可以得到正确的顺序。代码如下: #比较单个字符 def comp_char_PY(A,B): if A==B: return -1 pyA=searchdict(dic_py,A) pyB=searchdict(dic_py,B) if pyA > pyB: return 1 elif pyA < pyB: return 0 else: bhA=eval(searchdict(dic_bh,A)) bhB=eval(searchdict(dic_bh,B)) if bhA > bhB: return 1 elif bhA < bhB: return 0 else: return 'Are you kidding?' #比较字符串 def comp_char(A,B): charA = A.decode('utf-8') charB = B.decode('utf-8') n=min(len(charA),len(charB)) i=0 while i < n: dd=comp_char_PY(charA[i],charB[i]) if dd == -1: i=i+1 if i==n: dd=len(charA)>len(charB) else: break return dd # 排序函数 def cnsort(nline): n = len(nline) lines='n'.join(nline) for i in range(1,n): #插入法 tmp = nline[i] j = i while j > 0 and comp_char(nline[j-1],tmp): nline[j] = nline[j-1] j -= 1 nline[j] = tmp return nline 现在我们就可以按照字典的规范给中文排序了。 char=['赵','佘'] char=cnsort(char) for item in char: print item.decode('utf-8').encode('gb2312') 终于得到了“李钱佘孙赵”,示例文件点此下载。 这里我没有考虑多音字的情况。如果想让程序自动识别,可以增加多音词组对照表,通过上下文来判断。我不知道哪里有这样的数据,反正对于多音字不太多的情形,手动调整也就够了。 PS:这里再为大家推荐2款比较实用的相关在线排序工具供大家参考使用: 在线中英文根据首字母排序工具: 在线文本倒序翻转排序工具: 更多关于Python相关内容可查看本站专题:《Python正则表达式用法总结》、《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》 希望本文所述对大家Python程序设计有所帮助。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |