用Python从《诗经》中取平仄相对的名字

项目背景

通常父母取名有‘女诗经男楚辞’之说(至于说得是否在理,另当别论,文末举一反三)。同时还兼顾姓名发音的平仄相对,听起来朗朗上口,最后能兼顾笔画简单就更好。
本文以取两个汉字,其声调分别是三声和二声的名字为例,从《诗经》的每行诗句中取出符合条件的字,组成名字。

  1. 字:计算单个汉字的笔画数和声调(一二三四声)
  2. 词:提取单条诗句中符合条件的二字词
  3. 句:从诗经的json文件中切割出所有的句子
  4. 篇章:统计诗经中所有满足条件的二字名字

解决方案

获取汉字的笔画数

从 汉字编码表 gbk unicode.txt 文本文件里获取每个汉字的笔画数,自第七行开始是规则的行列数据,如下图。该功能本项目暂没启用。
汉字编码表 gbk unicode

#计算汉字笔画数
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",回复“诗经取名”,可获取完整源代码。
也可从唐诗文件中为男宝宝取名。取名思路参考 给孩子起名字/取名字/命名有哪些优雅的思路?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值