python+jieba处理唐诗三百首
-
代码及源文件地址:poem_300 代码保证符合命名规范、遵循PEP8规则、导包顺序清晰、尽量做到复用性和不罗嗦- 记得修改文件路径哟(^U^)ノ~YO
-
如果有帮到您,还请给个评论或star~ 蟹蟹
1.题目描述:
俗话说,熟读唐诗三百首,不会吟诗也会吟’,请分析附件的唐诗300首文本文件。
完成下列功能:(部分功能需要使用jieba第三方库)
-
统计每首诗歌的作者,如果第一行输入‘作者’,第二行则输入一个整数n,输出出现最多的作者前n个,每行输出一个名字和出现次数,以空格间隔,程序结束
-
统计出现的人名,如果第一行输入‘人物’,第二行则输入一个整数n,输出出现最多的人名前n个,每行输出一个名字和对应出现次数,以空格间隔,程序结束
注:有的诗人在诗名或诗句中用到了别的诗人的名字。如“梦李白二首之一”。因此第1、2项目之间的数据可能有所差异。 -
如果输入某个字符串编号,范围和格式在“010-320之间(测试用例保证编号存在),输出对应该编号的诗句。
输出格式:去掉首行诗歌编号,其余格式与文件中诗歌显示格式相同。 -
如果输入‘唐诗,输出文件中的诗词数量,程序结束
-
飞花令,如果第一行输入飞花,则可以在第二行输入中文字符(长度为1),然后按照在文件中出现的顺序,输出唐诗300首文件包含该中文字符的诗句(长度不超过7的诗句),每行一句。
-
如果非以上输入,输出‘输入错误’,程序结束
2.细节分析
- 统计作者
观察源文件规律,发现作者名都在三个数字字符和一个空格之间出现:
因此正则表达式用r'\d{3}(.+?) '模式匹配,\d{3}代替三个数字字符,(.+?)是我们要发现的部分,为什么用.+?而不是.*,前者是惰性匹配(加个?号),若是011杜甫 梦李白二首之一 测试,不用惰性匹配,就会找到杜甫 梦李白二首之一,使用惰性匹配只会匹配到杜甫(第一个空格前的内容,理解成尽可能少即可)
参考地址: Python 正则表达式 - 统计人名
主要将第一步骤的代码复用、拿到作者清单,然后将古诗全文当作一个大的字符串,用jieba切词之后判断出是作者的词,这里代码罗嗦了一下,有两条没用的判断条件(我在等若要的是诗句中非作者的话,我就重新修改判断逻辑) - 输入字符串编号获得古诗
这个参考第一步骤的正则匹配,本题的思路是匹配传进来的三个数字字符和其他三个数字字符之间的内容(惰性匹配),然后再去掉一个空格两个换行符即可:
但是有个特殊情况—— 最后一首诗,应该改成传入的三个数字字符串和文件结尾之间的内容,然后再去掉换行符 - 输入“唐诗”得到诗词总数目并结束
数目的话根据第一步骤的作者的数目即可(不要去重,有些诗共同拥有一位作者!) - 输入“飞花”后输入一个中文字获得长度小于7的包含该字的诗句
这里需要注意的点是if not bool(re.search(r'\d', item))来判断非诗名的行和将诗句根据空格拆分成单句然后再判断含有某个中文字符的句子即可。 -
函数总入口
根据题目的描述,需要注意几点:
- 需要退出程序的地方有俩——输入
唐诗和输入错误,一个给if flag == ’唐诗‘,一个留到最后给else:即可 - 观察得知,这些题目都至少需要输入一个字符串,然后有的需要再输入另一个字符串,所以拿第一个字符串当标志flag,根据情况判断需不需要接收第二个字符串然后调函数,input()接受的字符串都是str类型的,所以有的接受n的地方n需要转成整形,这些都统一在路由的位置处理了,所以其他各自处理逻辑的函数不需要考虑类型,直接使用即可。
3.测试案例
- 输入“作者,”统计作者
- 输入“人物”,统计人名
- 输入字符串编号获得古诗
- 输入“唐诗”得到诗词总数目并结束
- 输入“飞花”后输入一个中文字获得长度小于7的包含该字的诗句
- 错误输入打印“输入错误”后退出
4.总结
- 用到比较多的是
re正则表达式,通过本次编程练习,熟悉了以前生疏的re正则匹配(匹配单行和多行、贪婪和不贪婪的区别) - 熟悉了使用过的jiaba第三方库的
词性 词性表
| 标签 | 含义 | 标签 | 含义 | 标签 | 含义 | 标签 | 含义 |
|---|---|---|---|---|---|---|---|
| n | 普通名词 | f | 方位名词 | s | 处所名词 | t | 时间 |
| nr | 人名 | ns | 地名 | nt | 机构名 | nw | 作品名 |
| nz | 其他专名 | v | 普通动词 | vd | 动副词 | vn | 名动词 |
| a | 形容词 | ad | 副形词 | an | 名形词 | d | 副词 |
| m | 数量词 | q | 量词 | r | 代词 | p | 介词 |
| c | 连词 | u | 助词 | xc | 其他虚词 | w | 标点符号 |
| PER | 人名 | LOC | 地名 | ORG | 机构名 | TIME | 时间 |
- jieba掌握了新技巧——提升jieba日志级别
关闭jieba debug日志输出jieba.setLogLevel(logging.INFO) - jieba理解了新技巧——手动初始化jieba
jieba.initialize(),在导包后即初始化jieba,不需要每次在函数中初始化了 -
Counter方法统计频次 -
sorted方法中key用lambda函数可以根据某元素排序(在AD域中使用过的排序有根据多条件的更为复杂) - 用
列表推导式去除列表对象content中每一个元素的换行符、空字符[x.strip() for x in content if x.strip() != ‘’] ,以此代替for循环提高运行速度
以上涉及的点均是写python以来习惯使用的东西,仅关于python的点有些能提高代码速度,请多多熟悉使用~