首先以只读方式打开单词文件,利用列表推导式创建两个列表
列表sta记录各单词出现的次数,列表freq记录各单词出现的频率
1
2
3
|
f = open ( '5500词.txt' , 'r' ,encoding = 'utf-8' ) sta = [ 0 for i in range ( 26 )] freq = [ 0 for i in range ( 26 )] |
单词格式如下所示:
a [ei] art.一(个);每一(个);(同类事物中)任一个
abandon [ə'bændən] vt.离弃,丢弃;遗弃,抛弃;放弃
abdomen [æb'dəumen] n.腹,下腹(胸部到腿部的部分)
abatement [ə'beitmənt] n.减(免)税,打折扣,冲销
abide [ə'baid] vi.(abode,abided)(by)遵守;坚持;vt.忍受,容忍
每行一个单词,所以我们选择按行读取文件
1
2
|
for i in range ( 5500 ): buf = f.readline() |
然后依次统计每个字符串中的字母个数,注意大写字母也要统计(后面的字母省略)
1
2
3
4
5
|
for j in buf: if j = = 'a' or j = = 'A' : sta[ 0 ] = sta[ 0 ] + 1 elif j = = 'b' or j = = 'B' : sta[ 1 ] = sta[ 1 ] + 1 |
注意到每个单词后都有音标,所以遇到 中括号" [ "时停止计数
1
2
|
if j = = '[' : break |
然后每五个一行,依次输出各个单词出现的次数,将print函数中的end参数由默认换行改成几个空格,使输出更格式化。字母利用ASCII码输出
1
2
3
4
5
6
7
8
9
10
|
print ( '5498个词汇中,各字母出现的次数分别为:\n' ) asc = 97 for i in range ( 26 ): if i < 25 : print ( "%c" % asc, ':' ,sta[i],end = ' ' ) if (i + 1 ) % 5 = = 0 : print ( '\n' ) else : print ( "%c" % asc, ':' ,sta[i]) asc = asc + 1 |
利用一个for遍历计算出所有字母数量的总和
1
2
3
|
sum = 0 for i in sta: sum = sum + i |
利用一个for遍历计算出各字母出现的频率,注意到Python中计算出的频率会自动保留17位小数,为了方便查看,使用round()函数保留四位小数,值得注意的是,使用round()函数会自动去掉数字末尾的0
1
2
|
for i in range ( 26 ): freq[i] = round (sta[i] / sum , 4 ) |
再以每五个一行,依次输出各个单词出现的频率,将print函数中的end参数由默认换行改成几个空格,使输出更格式化。字母利用ASCII码输出。
1
2
3
4
5
6
7
8
9
|
print ( '各字母出现的频率分别为:\n' ) for i in range ( 26 ): if i < 25 : print ( "%c" % asc, ':' ,freq[i],end = ' ' ) if (i + 1 ) % 5 = = 0 : print ( '\n' ) else : print ( "%c" % asc, ':' ,freq[i]) asc = asc + 1 |
最后输出的结果如下图所示:
上概率论的课时,偶然看见居然有人拿着词典去数字母的数量,就想能不能写一个自动统计的程序,于是就随便写着玩。代码功底很差,所以写得很丑(居然有25个elif),所以看个乐呵就好了。
总的来说,我觉得有这些可以改进的地方:
①读取单词的方法可以改进,这种一行一行读取的方式,对格式要求很高,很难找到
②用字典来存储频数和频率是否会更好?后面输出的时候可以避免使用ASCII码,但是字典推导式我属实记不清了
③判断计数的这些if和elif能否抽象出一个方法?增加代码复用
④round()函数会自动去掉小数后面的0,有没有什么方法使0被保留下来?这样输出的格式会更好看
我的代码的优点估计只有一点了:
①Python初学者就能看懂
到此这篇关于利用Python3实现统计大量单词中各字母出现的次数和频率的方法的文章就介绍到这了,更多相关Python3字母出现次数和频率内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.csdn.net/firm_mabu/article/details/114420702