项目背景
通常父母取名有‘女诗经男楚辞’之说(至于说得是否在理,另当别论,文末举一反三)。同时还兼顾姓名发音的平仄相对,听起来朗朗上口,最后能兼顾笔画简单就更好。
本文以取两个汉字,其声调分别是三声和二声的名字为例,从《诗经》的每行诗句中取出符合条件的字,组成名字。
- 字:计算单个汉字的笔画数和声调(一二三四声)
- 词:提取单条诗句中符合条件的二字词
- 句:从诗经的json文件中切割出所有的句子
- 篇章:统计诗经中所有满足条件的二字名字
解决方案
获取汉字的笔画数
从 汉字编码表 gbk unicode.txt 文本文件里获取每个汉字的笔画数,自第七行开始是规则的行列数据,如下图。该功能本项目暂没启用。
#计算汉字笔画数
def number_of_bihua(w):
# data_lines = open(u'汉字编码表 gbk unicode.txt').readlines()
with open(u'汉字编码表 gbk unicode.txt') as f_in:
for line in f_in.readlines()[6:]:#各汉字笔画数从第七行开始
line = line.strip().split()
if line[0]==w.strip():#line[0] line[6] 分别表示当前行的汉字和所对应的笔画数
return line[6]
安装pypinyin库获取汉字的拼音(含声调)
pip install pypinyin
from pypinyin import pinyin, lazy_pinyin, Style
#调用pypinyin库获取汉字的拼音(含声调)
def tone_of_word(w):
#如,u'中'的拼音为 [[u'zho1ng']] ,输出的结果:u'zho1ng'
pyin=pinyin(w, style=Style.TONE2)[0][0]
return "".join(list(filter(str.isdigit, pyin))) #返回数字音调
返回诗句中所有汉字的笔画和声调
某个汉字的笔画和声调,返回的数据结构为元素是字典类型的列表。
如:输入“一二三”, 输出:[{‘word’:‘一’,‘bihua’:‘1’,‘tone’:‘1’},{‘word’:‘二’,‘bihua’:‘2’,‘tone’:‘4’}{‘word’:‘三’,‘bihua’:‘3’,‘tone’:‘1’}]
def lst_bihua_tone(sentence):
dic={}
lst=[]
sentence=sentence.replace(',','')#去掉句子中的标点符号
for word in sentence:
dic['word']=word
dic['bihua']=number_of_bihua(word)
dic['tone']=tone_of_word(word)
lst.append(dic.copy())
return lst
获取当前行中所有符合条件的汉字所组成的词
以元素是字典类型的列表形式,返回当前行中所有符合条件的汉字所组成的词,其中字典的name表示二字词,字典的sentence表示该二字词所在的诗句。
使用itertools.combinations返回句子中所有二字词的有序组合,如“在河之洲”,返回的结果是:[(‘在’, ‘河’), (‘在’, ‘之’), (‘在’, ‘洲’), (‘河’, ‘之’), (‘河’, ‘洲’), (‘之’, ‘洲’)]
而itertools.permutations返回的结果是无序的排列,如“在河之洲”,permutations后返回
[(‘在’, ‘河’), (‘在’, ‘之’), (‘在’, ‘洲’), (‘河’, ‘在’), (‘河’, ‘之’), (‘河’, ‘洲’), (‘之’, ‘在’), (‘之’, ‘河’), (‘之’, ‘洲’), (‘洲’, ‘在’), (‘洲’, ‘河’), (‘洲’, ‘之’)]
from itertools import combinations
import itertools
def candiate_name_in_sentence(tone:str,sentence):
dic={}
lst_name_sentene=[]
lst_tone=[x['tone'] for x in lst_bihua_tone(sentence)]
index_lst=list(itertools.combinations(enumerate(lst_tone), len(tone)))
s=sentence.replace(',','')
for x in index_lst:
if tone==x[0][1]+x[1][1]:
name=s[x[0][0]]+s[x[1][0]] #"巧笑倩兮美目盼兮"[x[0][0]]+"巧笑倩兮美目盼兮"
# print(name)
dic['name']=name
dic['sentence']=sentence
lst_name_sentene.append(dic.copy())
return lst_name_sentene
从诗经的json文件中返回所有句子列表
切分的标准是句号
import json
def sentence_from_json(jsonfile):
lst_sentencs=[]
with open(jsonfile,encoding='utf-8') as f_in:
json_data = json.load(f_in)
for line in json_data:
lst_sentencs.extend(line['content'][0].split('。'))#句号分割
return lst_sentencs
项目综合实现
项目中所有的汉字编码表和诗经文件可在附件中下载。
像“采言”,“有乔”来自“南有乔木,不可休息”,这些名字还是听起来不错的。
结合笔画统计函数number_of_bihua,作个升序排列,还能筛选出书写也方便的名字。
# 女诗经男楚辞’之说,用好声调,讲究平仄
if __name__ == '__main__':
#获取json文件中所有的诗句,以列表形式返回
sentences=sentence_from_json('shijing.json')
for sentence in sentences:
result=candiate_name_in_sentence('32',sentence)#32字符串表示名字中取声调分别是三声和二声的汉字
if result:#过滤掉无符合条件的空列表
print(result)
运行结果截图:
举一反三
关注公众号"乐享Python",回复“诗经取名”,可获取完整源代码。
也可从唐诗文件中为男宝宝取名。取名思路参考 给孩子起名字/取名字/命名有哪些优雅的思路?