起因

本人现在所在的公司是由香港人开办的,也是做做香港业务,一个车辆管理系统后台,也包括司机等人员管理。突然有一天,老板说我们的列表找司机不够人性化,不符合用户习惯。因为我们Python对中文排序默认是按照Unicode编码来排序的,很正常嘛,一般都喜欢希望按照拼音来排序。然后我就惊呆了:香港人不会拼音… 那按照五笔排序?也不是,他们要按照汉字的笔画数量排序,笔画少的,排在前面。

额…(靓仔语塞.jpg)

不过既然老板需要,那还是要搞起来的

如果不是做香港业务,我可能永远也不会想到中文排序除了【按照拼音排序】,【按五笔排序】之外,还有什么什么排序。

香港人打字不用拼音,他们用仓颉输入法

实现

思路

首先百度了一大圈,即使强如Python,也没有现成可用的第三方库可用,不过有些思路和代码片段,但是都不怎么完善,需要自己实现。

首先要找一个文件,包含所有汉字,并且有每个汉字对应的笔画数,然后构造成一个字典,字典的键是汉字,值是对应的笔画数。之后计算汉字的笔画数时,就到字典中去取就可以了。

最难找的就是找个汉字对照表文件了,找到了下载还有层层限制,要各种下载币

代码实现

所需用到的字典文件放到gitlab中了,有需要的可自行下载

汉字对照表地址:https://github.com/WuChengqian520/codeSnippet.git

代码如下:

from typing import Iterable, Callable, Union# 加载汉字笔画对照文件,参考同级目录下的 chinese_unicode_table.txt 文件格式
chinese_char_map = {}
with open('./chinese_unicode_table.txt', 'r', encoding='UTF-8') as f:lines = f.readlines()for line in lines[6:]:  # 前6行是表头,去掉line_info = line.strip().split()# 处理后的数组第一个是文字,第7个是笔画数量chinese_char_map[line_info[0]] = line_info[6]def __sort_by_strokes_core(words: Iterable) -> int:"""统计字符串中所有文字的笔画总数:param words: 需要统计的字符串:return: 笔画总数"""strokes = 0for word in words:if 0 <= ord(word) <= 126:  # 数字,英文符号范围strokes += 1elif 0x4E00 <= ord(word) <= 0x9FA5:  # 常用汉字Unicode编码范围4E00-9FA5,20902个字strokes += int(chinese_char_map.get(word, 1))else:  # 特殊符号字符一律排在最后strokes += 1return strokesdef __sort_by_sequence_core(words: Iterable) -> Iterable[int]:"""计算字符串中各个字符的优先级,组成数组返回,用于后面排序,优先排数字,再拍英文字母,最后排汉字, 为了确保汉字排在后面,所有汉字在笔画数量基础上再 +1000:param words: 需要统计的字符串:return: 字符串中字符笔画数列表"""weight = []for word in words:if 0 <= ord(word) <= 126:  # 数字,英文符号范围weight.append(ord(word))elif 0x4E00 <= ord(word) <= 0x9FA5:  # 常用汉字Unicode编码范围4E00-9FA5,20902个字weight.append(1000 + int(chinese_char_map.get(word, 0)))else:  # 特殊符号字符一律排在最后weight.append(99999)return weightdef sort_by_strokes(object_list: Iterable,model: str = 'sequence',key: Union[Callable, None] = None,reverse=False) -> Iterable:"""根据笔画数量对中文字符串进行排序:param object_list: 文字字符串列表:param model: 排序模式,sequence--按照文字笔画依次排序, total--按照笔画总数排序,默认:sequence:param key: 文字字符串列表:param reverse: 倒序排序:return: 排序后的字符串列表>>> name_list = ['张三', '李四', '王五', '赵六', '尼古拉丁', '周吴郑王']>>> print(sort_by_strokes(name_list))['王五', '尼古拉丁', '张三', '李四', '周吴郑王', '赵六']"""assert model in ['sequence', 'total'], '仅支持【sequence】和【total】两种模式'if model == 'sequence':_core_function = __sort_by_sequence_coreelse:_core_function = __sort_by_strokes_core__order_key = '__sort_weight'sorted_obj = []for obj in object_list:words = key(obj) if key else objassert isinstance(words, Iterable), '用于排序的对象必须是一个可迭代对象, 其他类型请自行实现!'strokes = _core_function(words)# 构建一个新的字典,用于存放排序对象和排序权重,后面根据权重进行排序后再取出对象sorted_obj.append({'obj': obj, __order_key: strokes})sorted_words = sorted(sorted_obj, key=lambda x: x[__order_key], reverse=reverse)# 取出排序后的对象sorted_words = [item['obj'] for item in sorted_words]return sorted_wordsif __name__ == '__main__':peoples = ['张三', '李四', '王五', '赵六', '尼古拉丁', '周吴郑王']print('普通排序:', sort_by_strokes(peoples))print('倒序排序:', sort_by_strokes(peoples, reverse=True))print('按照笔画总数排序:', sort_by_strokes(peoples, model='total'))students = [{'name': '王梓涵', 'sex': '男', 'age': 12, 'grade': 60},{'name': '周小静', 'sex': '女', 'age': 13, 'grade': 99},{'name': '张靓颖', 'sex': '女', 'age': 11, 'grade': 80},{'name': '欧阳晓晓', 'sex': '女', 'age': 14, 'grade': 67},{'name': '东方不败', 'sex': '男', 'age': 13, 'grade': 72},{'name': '周一天', 'sex': '男', 'age': 15, 'grade': 72},{'name': '♂卐', 'sex': '男', 'age': 13, 'grade': 72},]print('字典排序:', sort_by_strokes(students, key=lambda x: x['name']))

排序示例:

普通排序: ['王五', '尼古拉丁', '张三', '李四', '周吴郑王', '赵六']
倒序排序: ['赵六', '周吴郑王', '李四', '张三', '尼古拉丁', '王五']
按照笔画总数排序: ['王五', '张三', '李四', '赵六', '尼古拉丁', '周吴郑王']
字典排序: [{'name': '王梓涵', 'sex': '男', 'age': 12, 'grade': 60}, {'name': '东方不败', 'sex': '男', 'age': 13, 'grade': 72}, {'name': '张靓颖', 'sex': '女', 'age': 11, 'grade': 80}, {'name': '周一天', 'sex': '男', 'age': 15, 'grade': 72}, {'name': '周小静', 'sex': '女', 'age': 13, 'grade': 99}, {'name': '欧阳晓晓', 'sex': '女', 'age': 14, 'grade': 67}, {'name': '♂卐', 'sex': '男', 'age': 13, 'grade': 72}]

最后,打个小广告

欢迎各位访问我的博客:foryou.cool

Python实现获取汉字笔画数,根据汉字笔画数量排序相关推荐

  1. C#中如何获取汉字的笔画数和汉字的拼音

    以前玩过一个游戏,输入两个人的名字然后点击缘分就能产生一段缘分测试的结果,后来经过分析知道是根据名字笔画数之差来弄的小游戏,于是就在百度上找怎么得到汉字的笔画数,也没找到自己想要的答案,问遍了所有的人 ...

  2. python xlrd获取excel行数_python xlrd 模块(获取Excel表中数据)

    一.安装xlrd模块 到python官网下载http://pypi.python.org/pypi/xlrd模块安装,前提是已经安装了python 环境. 二.使用介绍 1.常用单元格中的数据类型 0 ...

  3. 汉字的奥秘: 获取汉字的笔画数

    汉字的奥秘: 获取汉字的笔画数 想想看,如果你需要在代码里面得到汉字的笔画数,该怎么办呢?每到这个时候,我们就一直感慨咱汉字的复杂啊 网上搜了一下,能看到的解决方案大抵都是说把所有汉字的笔画预先记录好 ...

  4. java获取汉字笔画数

    转自:https://blog.csdn.net/baidu_18987603/article/details/53375195?tdsourcetag=s_pcqq_aiomsg java获取汉字笔 ...

  5. 获取GBK编码的汉字笔画数

    GBK编码的汉字大概20000个左右,简繁两种字体的笔画数都可以得到,以下是源代码: 代码比较简单,重点在配置文件中,由于文件的内容比较多没办法为大家展示出来,有需要的朋友可以留下自己邮箱,我给你们发 ...

  6. C# 计算中文汉字笔画数

    C# 计算中文汉字笔画数 using System;   using System.Collections.Generic; using System.Linq; using System.Text; ...

  7. 巧用Excel笔画排序,实现计算汉字笔画数

    点赞再看,养成习惯:皮之不存,毛将焉附. 微信搜索[亦心Excel]关注这个不一样的自媒体人. 本文 GitHub https://github.com/hugogoos/Excel 已收录,包含Ex ...

  8. 如何快速计算汉字笔画数

    今天跟大家分享一下如何快速计算汉字笔画数 1.首先我们将要计算笔画的汉字复制到Excel中. 2.然后选中单元格区域 3.点击diy工具箱(Excel工具箱,百度即可了解详细下载安装信息,本文这里就不 ...

  9. 用java实现汉字的笔画数(转贴)

    public class CnToStrokeCount { /** * 测试 * @param args String[] */ public static void main(String[] a ...

最新文章

  1. 前端学习(2328):angular之模板
  2. c 复杂的前置后置面试题_你被哪些C语言面试题坑过?
  3. com线程模型实验之三
  4. javascript作用域链详解
  5. 单片机编程软件很简单(11),Keil单片机编程软件在线调试
  6. 揭秘springboot集成tomcat原理
  7. php h5 调用摄像头_怎样使用H5调用摄像头
  8. 网易游戏大咖专访丨《第五人格》主创团队畅谈游戏研发修炼记
  9. 三角函数公式和图像大全
  10. shiro中的过滤器
  11. 第二个重要极限的证明 e怎么出来的
  12. 读《京东咚咚架构演进》有感
  13. r去掉向量中的空字符串 在R里如何去掉字符串矩阵中的空字符串 r r 识别字符串中的双引号 识别字符串中的双引号 str_detect
  14. 项目管理过程中六种冲突解决方法
  15. 10首现代诗歌欣赏:什么是孤独
  16. HTML5新特性(基本)
  17. Android发展趋势分析
  18. 读书笔记---Head First 设计模式--- 装饰者模式
  19. 秋月之谋:5.21黄金震荡先空一次,原油依然强势
  20. 我对软件测试行业的看法

热门文章

  1. 奔腾G7400怎么样 相当于什么水平
  2. 《从0到1》笔记 第一章 未来的挑战
  3. jointjs Element
  4. FFT变换前后的幅值对应关系
  5. 发那科pmc地址分配_(完整版)FANUC PMC 地址表
  6. HoloWAN网络损伤仪带宽限制功能的介绍
  7. CC2640R2F BLE5.0 开发工具集
  8. Ubuntu下系统重启dns就被清空的解决方案
  9. 显示12306服务器处理中正在排队,12306一直在排队中怎么办
  10. 云服务器租赁招标文件,云服务器招标文件