尧图精选

用Python构建汉字拼音数据文件:JSON与TXT双重导出实战

🕒 发布时间:2026/9/8 10:53:11 📁 来源:尧图网络
简介这是一份面向中文信息处理学习者、语言教学者和开发者的汉字拼音对照数据包内置20850个常用汉字的拼音数据覆盖声母、韵母和声调信息。资源以纯文本和JSON两种格式存储同一份数据纯文本轻量易读适合人工查阅和编辑JSON结构清晰便于程序解析与数据交换压缩包中还附带一个Python转换脚本可一键将纯文本转换为JSON并支持进一步做拼音统计、词典生成或接入其他应用。资源共3个文件压缩包大小仅174KB轻量不占空间目前已有504人学习下载适合备考、备课或快速集成到项目中。对初学者可对照拼音纠正发音对教师是现成的教学辅助素材对开发者则省去了整理海量拼音数据的时间拿来即可用于输入法、语音识别或自然语言处理等场景。1. 项目概述为什么我需要一份“汉字对应拼音”的数据先交代一下背景。前段时间我在折腾几个和小语种学习相关的工具需要把一批生僻字、常用字批量转成拼音用于生成发音对照表。结果翻遍了网上现成的“汉字-拼音表”要么年份太久远要么格式混乱——有的带声调符号有的是纯数字音调还有的是繁体字、异体字混在一起根本没法直接用。最头疼的是很多热门的开源词库只提供单一格式我想要一份既能导入数据库、又能快速浏览的拼音对照数据愣是没找到完全满意的。于是干脆自己动手做了一份“汉字对应拼音”的数据文件同时输出成txt和json两种格式txt方便人肉眼检查和打磨json方便程序直接解析、灌库或者做接口返回。这篇文章就把整个思路、代码、踩坑过程都梳理出来如果你也在做汉字转拼音相关的开发或者只是想找一份靠谱的“汉字-拼音”数据希望对你有所帮助。2. 整体设计格式选型与工具链选择2.1 为什么同时要 txt 和 json先说结论这两种格式不是重复而是分工不同。txt 格式适合做“字典式校验”。用文本编辑器打开一眼就能看到汉字和拼音的对应关系方便人工核对、排序、去重甚至可以直接扔给 Excel 做二次处理。json 格式适合做“程序化消费”。现代后端接口、数据库导入、前端工具都习惯用 JSON因为结构清晰、层级明确尤其适合映射关系key-value的存储也方便后续扩展增补字段比如加入词性、频率、释义等元数据。我当时的需求是一方面要把这份表直接塞进一个内部的小型查询服务里程序读 JSON 最省事另一方面团队里的运营同学要手动校对一批生僻字显然只能给他们 txt。所以“一份源数据两种导出格式”是性价比最高的方案。2.2 技术选型为什么用 Python整个项目最核心的工作是拿到“汉字—拼音”的映射数据然后格式化输出。这里我最终选择了 Python 来完成原因很直接生态成熟处理文本、编码、JSON 这些任务Python 几乎是零成本的不需要额外搭建编译环境。库支持好Python 的pypinyin是汉字转拼音领域最流行的库多音字处理能力不错还支持声调、轻声等多种输出风格。JSON 原生支持Python 标准库自带json模块序列化、缩进、编码控制都很方便。当然如果你只是想要一份静态数据文件不用写代码也行——网上有很多现成的“3500常用汉字拼音表”但它们的格式和质量参差不齐建议还是自己跑一遍脚本生成最稳妥。3. 核心实现从零构建拼音数据文件3.1 源数据准备一个汉字的列表就够了说白了这个项目的输入其实只需要一个东西你想转换的汉字列表。我这边用的是“现代汉语常用字表”的前3500个汉字覆盖日常阅读的绝大部分另外还手工补充了一批生僻字、多音字和地名用字。如果你不想自己整理汉字列表有几个方案从公开的常用字表比如“现代汉语常用字表”复制文本存入一个.txt文件作为输入源。直接使用 Unicode 编码范围生成汉字集合\u4e00到\u9fff是 CJK 统一汉字的基本区可以按需生成全量汉字再过滤。如果你有业务场景的专用词表比如医疗、法律、财经等领域的术语表直接作为输入也可以。我这个示例先用一个较小的可控列表来演示流程# 汉字列表这里展示一部分实际可以读外部文件 hanzi_list [ 中, 国, 汉, 字, 拼, 音, 重, 行, 乐, 长, 的, 了 ]3.2 核心转换逻辑pypinyin 的正确用法pypinyin库的使用非常简洁但有几个细节要注意。第一步肯定是安装库pip install pypinyin基础用法如下from pypinyin import pinyin, Style # 默认风格带声调 print(pinyin(中国)) # [[zhōng], [guó]]这里返回的是嵌套列表因为一个汉字可能对应多个读音多音字pypinyin会按照上下文语境自动选择最可能的读音并通过列表返回所有候选读音。对于我们的“汉字-拼音”映射表来说一般只需要取第一个候选读音最常用读音作为结果。完整的转换脚本长这样from pypinyin import pinyin, Style import json import os def hanzi_to_pinyin(hanzi_list): 把汉字列表转换为拼音字典 result {} for hz in hanzi_list: # 跳过空字符串和非法字符 if not hz.strip(): continue py_list pinyin(hz, styleStyle.TONE, heteronymTrue) # 取第一个读音作为常用读音 primary py_list[0][0] if py_list else # 把所有候选读音都保留下来后续可能有用 alternatives [item[0] for sublist in py_list for item in sublist] result[hz] { primary: primary, alternatives: alternatives, length: len(hz) } return result很多人第一次用pypinyin会踩一个坑heteronymTrue参数。如果不加这个参数多音字只返回一个读音但加上之后返回结构会变成“每个字对应一个包含多个读音的列表”。如果只是简单取第一个两种模式下返回结构不一样需要灵活处理。3.3 两种导出格式的实现细节接下来就是导出环节。txt 和 json 的导出实际上是在同一个内存字典上做不同的序列化处理。txt 格式我用的是最直观的“汉字 → 拼音”的表格形式def export_txt(data, filepath): 导出 txt 格式每行一个汉字格式为 汉字: 拼音 with open(filepath, w, encodingutf-8) as f: for hz, info in data.items(): f.write(f{hz}: {info[primary]}\n)json 格式我保留了完整的信息结构主读音、候选读音、笔画数等元信息这样后续扩展更容易def export_json(data, filepath): 导出 json 格式完整的拼音数据 with open(filepath, w, encodingutf-8) as f: json.dump(data, f, ensure_asciiFalse, indent2)这里有一个重要参数ensure_asciiFalse。如果不设置json.dump会把所有汉字转成\uXXXX形式的 Unicode 转义序列生成的文件人眼完全没法看而且很多上层应用解析时还会多一道解码步骤。实测中我见过太多人忘记这个参数导出的 JSON 里全是\u4e2d\u56fd这种编码排查起来非常痛苦。3.4 完整流程串联把它们串起来就是一个完整的工具脚本def main(): # 步骤1读取汉字列表可以从文件读 with open(hanzi_list.txt, r, encodingutf-8) as f: content f.read() # 按字符拆分保留所有汉字 hanzi_list [ch for ch in content if ch.strip()] # 步骤2转换 data hanzi_to_pinyin(hanzi_list) # 步骤3导出 os.makedirs(output, exist_okTrue) export_txt(data, output/hanzi_pinyin.txt) export_json(data, output/hanzi_pinyin.json) print(f转换完成共 {len(data)} 个汉字) print(txt 文件output/hanzi_pinyin.txt) print(json 文件output/hanzi_pinyin.json) if __name__ __main__: main()输出的hanzi_pinyin.json大概长这个样{ 中: { primary: zhōng, alternatives: [zhōng, zhòng], length: 1 }, 国: { primary: guó, alternatives: [guó], length: 1 } }输出的hanzi_pinyin.txt长这样中: zhōng 国: guó 汉: hàn 字: zì 拼: pīn 音: yīn到这里一个可用的“汉字对应拼音”数据就生成完了。4. 实操过程中的关键坑与优化方案4.1 编码问题UTF-8 无 BOM 有多重要这是整个项目里最血泪的一条经验。早期我生成 txt 的时候直接用encodingutf-8写完结果编辑器打开没问题但运营同学的 Windows 机器上打开全是乱码。后来排查才发现问题出在UTF-8 的 BOM 头上。默认的utf-8编码是不带 BOM的而 Windows 上的记事本老版本默认用 ANSIGBK打开纯文本文件如果文件是 UTF-8 无 BOM它可能识别错误导致乱码。解决方案有两个方案A在文件开头手动加 BOM 头即utf-8-sig编码让 Windows 记事本自动识别。方案B保持无 BOM但对使用者做说明要求他们用现代编辑器Notepad、VS Code、Sublime打开。我后来的处理方式比较灵活txt 文件默认用utf-8-sig输出json 文件保持utf-8无 BOM 输出因为大多数服务端程序解析 JSON 时如果带头 BOM 反而会报错。代码改动很小# txt 导出用 utf-8-sig with open(filepath, w, encodingutf-8-sig) as f: ... # json 导出用 utf-8 with open(filepath, w, encodingutf-8) as f: ...如果你是自己写程序读取这些文件也一定要在读取时显式声明编码避免依赖默认编码导致的跨平台坑。4.2 多音字怎么处理只取第一个读音真的够吗做汉字转拼音最大的坑永远是多音字。比如“行”字在“行动”中读xíng在“银行”中读háng“乐”在“快乐”中读lè在“音乐”中读yuè。pypinyin默认的智能模式会根据上下文判断读音但这里有个前提它是基于词语语境判断的如果只传入单个汉字“行”它大概率会返回一个默认读音一般是出现频率最高的那个这不一定符合你实际使用场景。针对这个问题我做了三个层次的优化保留候选读音在/alternatives字段中保留全部读音即使主字段不够准确人工或程序仍然能拿到完整信息。支持词组输入如果你的数据源不是单字而是词语建议直接传整个词语给pypinyin这样多音字的准确率会大幅提升。人工后处理针对少量业务中常见但pypinyin判断错误的多音字准备一个“纠错表”进行覆盖修正。举个例子如果我不小心把“重庆”这个地名纳入词表pypinyin默认可能会读成zhòng qìng这时候可以这样处理# 自定义纠错表 correction { 重庆: chóng qìng, 音乐: yīn yuè, 银行: yín háng }然后在生成结果后对原文进行正则匹配替换。这一步看起来原始但在专用词表场景里非常实用。4.3 性能优化全量汉字转换会不会很慢如果你用的是完整 Unicode CJK 汉字表大概两万多字转换成拼音会不会很慢我实测下来pypinyin对两万多字做转换大概只需要几秒钟到十几秒钟取决于机器配置完全在可接受范围内。但如果你的数据源是动态的、且需要频繁转换比如一个在线接口每次都要转拼音那就不能每次都调用pypinyin现算而是应该提前生成映射表存到 Redis 或内存缓存里。这也是我最初做这份数据的重要原因——把计算量前置运行时只查表。一个简单的查询接口设计思路from flask import Flask, jsonify import json app Flask(__name__) # 启动时加载 json 数据到内存 with open(output/hanzi_pinyin.json, r, encodingutf-8) as f: PYIN_DATA json.load(f) app.route(/pinyin/char) def get_pinyin(char): if char in PYIN_DATA: return jsonify(PYIN_DATA[char]) return jsonify({error: not found}), 404这个接口可以跑在服务器上任何业务系统都能用它来查询汉字的拼音数据。用 JSON 格式做存储天然就是为这种“读多写少”的查询场景设计的。5. 数据源的扩展思路从“静态文件”到“动态服务”5.1 文件生成之后还能做什么很多朋友觉得生成两个文件就万事大吉了。其实只把它当静态文件用多少有点浪费。结合我自己的经验这组数据至少有这几种延伸用法数据库灌入先把 JSON 解析成行记录然后批量插入 MySQL/PostgreSQL字段设计可以是id, hanzi, primary_pinyin, alternatives, created_at。之后可以直接用 SQL 做复杂查询比如“查找所有读zhong的汉字”。前端本地检索把 JSON 文件压缩后放到前端静态目录用户输入汉字时前端直接通过字典查询拼音完全不需要后端参与。这在一些简单的单页应用如背单词工具里非常高效。拼音模糊搜索把拼音转为全拼、首字母索引存储在搜索引擎如 Elasticsearch里实现“输入拼音前缀/首字母就能搜出汉字”的搜索功能。这个在很多 App 的联系人搜索、商品搜索场景里都用得到。5.2 如果要支持词语、整句的拼音转换呢当前这版数据是按“单字”维度做的如果业务需要词语或整句的拼音最直接的做法是用pypinyin加Style.NORMAL、Style.FIRST_LETTER等不同风格来做扩展。全拼不带声调Style.NORMAL比如“中国”返回zhong guo。首字母Style.FIRST_LETTER比如“中国”返回z g。声调风格Style.TONE3数字标调比如“中国”返回zhong1 guo2。这些不同风格的拼音本质上只需要对同一份汉字数据做不同的格式化映射完全可以在导出时生成多个字段。我在输出 JSON 时除了primary带声调还可以增加primary_no_tone和initials字段这样数据的适用范围会宽很多。def hanzi_to_pinyin_extended(hanzi_list): from pypinyin import pinyin, Style result {} for hz in hanzi_list: if not hz.strip(): continue tone_py pinyin(hz, styleStyle.TONE, heteronymFalse)[0][0] no_tone_py pinyin(hz, styleStyle.NORMAL, heteronymFalse)[0][0] first_letter pinyin(hz, styleStyle.FIRST_LETTER, heteronymFalse)[0][0] result[hz] { tone: tone_py, normal: no_tone_py, first_letter: first_letter } return result这一版生成的数据就更丰富了完全可以支撑一个“输入汉字、输出多种格式拼音”的小工具。6. 常见问题与排查技巧速查表我在开发和交付这套数据的过程中遇到过不少问题加上团队同学也踩过一些坑整理成表格放在下面方便你下次直接对照排查。现象可能原因排查方法解决方案txt 文件在 Windows 记事本打开乱码文件是 UTF-8 无 BOMWindows 老版记事本按 ANSI 解码用 VS Code / Notepad 打开看右下角编码导出时用utf-8-sig编码json 文件里全是\uXXXXjson.dump未设置ensure_asciiFalse打开文件看内容确认代码参数设置ensure_asciiFalse多音字读音不符合预期只传了单字没有上下文或词表里本就是多音地名对比alternatives字段词组输入自定义纠错表JSON 解析报错 “missing field”数据结构对不上或文件被 BOM 头污染检查文件开头是否有 BOMJSON 统一用 UTF-8 无 BOMpypinyin返回嵌套列表取不到值不了解返回结构打印看数据类型按result[0][0]逐层取手写字符被过滤掉了if not hz.strip()的处理逻辑把空字符也跳过了检查源文件是否有全角空格用re.match(r[\u4e00-\u9fff], hz)过滤生成的 txt 每行末尾有空白字符大量使用f.write时混入多余空格用编辑器开启“显示空格”查规范化模板去除rstrip()大文本里个别汉字转换失败生僻字或扩展区汉字未收录打印异常上下文用错误日志定位后手工映射其中JSON 带 BOM 导致解析失败这个问题非常值得单独强调。很多 Windows 下写脚本的朋友习惯了给文件加 BOM结果生成 JSON 后后端服务直接报错错误信息像failed to deserialize the json body之类。这是因为 BOM 头\ufeff会被某些解析器当作非法字符。所以我的原则是txt 可以带 BOMjson 绝不带 BOM。7. 聊聊我对这份数据的后续规划如果只是给自己的小工具用这份数据已经足够了。但最近我在琢磨一个更完整的方案把“汉字-拼音”和“词语-拼音”合并到同一个 JSON 文件里通过不同的 key 前缀区分比如char:中、word:中国这样就可以覆盖字和词两种查询需求。另外一个想法是可以在 JSON 里增加拼音的“音调数字表示”字段——比如把zhōng转成zhong1。虽然pypinyin有现成的Style.TONE3但为了保证数据文件自包含最好在导出时就把各种风格都生成好避免业务方每次都要处理格式转换。这些功能我可能会在下个版本迭代里做进去。到时候生成的数据文件会比现在更通用不仅是自己用也可以分享给有同样需求的人省得大家重复造轮子。如果你对这份数据的格式、字段设计有自己的想法欢迎一起交流。毕竟这种基础的“字典数据”做得越规范后面用起来就越省心。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联 返回资讯列表 →