问题描述:
读取附件是一篇英文短文,请编写程序统计这篇短文前 n 行中每一个英文字母出现的次数,结果按次数降序排列,次数相同时,按字母表顺序输出。若 n 值大于短文行数,输出整篇文章中每一个英文字母出现的次数(大写字母按小写字母统计)。
输入格式:
输入一个正整数 n输出格式:
分行输出每个字母的数量,数量占3个字符宽度,居右对齐(参考示例输出)示例
输入:
10
输出:
e 的数量是 179 个
a 的数量是 125 个
t 的数量是 121 个
h 的数量是 116 个
o 的数量是 101 个
s 的数量是 92 个
i 的数量是 91 个
n 的数量是 88 个
d 的数量是 77 个
r 的数量是 60 个
l 的数量是 49 个
f 的数量是 46 个
w 的数量是 45 个
m 的数量是 41 个
y 的数量是 40 个
u 的数量是 35 个
c 的数量是 32 个
b 的数量是 29 个
g 的数量是 20 个
k 的数量是 19 个
p 的数量是 13 个
v 的数量是 9 个
q 的数量是 1 个
x 的数量是 1 个
j 的数量是 0 个
z 的数量是 0 个
因为有些小伙伴问,所以我干脆发这里。
先上代码和注释:
n = int(input()) # 输入需要统计的行数n
freq = {} # 创建一个空字典用来存储字母出现的次数
f=open("The Old Man and the Sea.txt", "r") # 打开文本文件
for i, line in enumerate(f): # 遍历每一行
if i >= n: # 如果行数大于等于n,则退出循环
break
for c in line: # 遍历每一个字符
if c.isalpha(): # 如果是字母
freq[c.lower()] = freq.get(c.lower(), 0) + 1 # 将字母转换为小写并统计出现次数,加入字典中
freq_list = sorted(freq.items(), key=lambda x: (-x[1], x[0])) # 对字典按照出现次数降序排序,如果出现次数相同,则按照字母表顺序排序
for item in freq_list: # 遍历字典
print("{} 的数量是 {:>3} 个".format(item[0], item[1])) # 输出字母和出现次数
for c in 'abcdefghijklmnopqrstuvwxyz': # 遍历所有小写字母
if c not in freq: # 如果字母没有出现过
print("{} 的数量是 {:>3} 个".format(c, 0)) # 输出字母和0次出现
这里面有注释,我已经对每一步做了详细的解释,另外,可能大多数人对sorted比较有疑惑。
那么再解释一下:
这行代码使用了 Python 的内置函数 sorted() 进行排序操作,对字典 freq 的每一项进行排序,排序规则由 key 参数指定,其中 key 接收一个函数作为参数,用于定义排序规则。
在这个例子中,lambda 表达式函数的作用是:对 freq.items() 中的每个元素(即键值对),先按照值(即出现次数)降序排列,再按照键(即字母顺序)升序排列。由于我们希望出现次数较多的字母排在前面,因此对值要取负数。
因此,sorted() 将字典 freq 按照指定规则进行排序,并将排序后的结果存储在列表 freq_list 中,其中每个元素是一个元组 (letter, count) ,表示字母及其出现次数。
具体解释:
在这个程序中,我们想要按照字母出现的次数排序,将出现次数较多的字母排在前面,如果出现次数相同,则按照字母的字典序排序。为了实现这个目的,我们使用了 sorted
函数的关键字参数 key
。 key
参数用于指定排序时每个元素应该按照什么规则来排序。
在这个程序中, freq.items()
返回一个列表,其中每个元素都是一个元组,第一个元素是字母,第二个元素是该字母出现的次数。例如: [('a', 3), ('b', 1), ('c', 2)]
。
我们将 key
参数设置为一个函数,这个函数返回一个元组,第一个元素是字母出现的次数的相反数,第二个元素是字母本身。因为我们要按照出现次数的相反数排序,所以我们用 -x[1]
,而如果出现次数相同,则按照字母本身排序,所以我们用 x[0]
。
lambda x: (-x[1], x[0])
是一个lambda函数,这个函数有一个参数x,并返回一个元组,其中第一个元素是-x[1](即频率的相反数),第二个元素是x[0](即字母本身)。这个lambda函数作为sorted函数的key参数传入,表示按照元组的第一个元素(即频率的相反数)进行降序排序,若第一个元素相同时,按照元组的第二个元素(即字母本身)进行升序排序。这样就可以实现按照频率进行降序排列,若频率相同时按照字母顺序输出的效果。
再具体说一下lambda:
lambda
函数的语法格式如下:lambda 参数列表: 表达式
其中,参数列表可以包含多个参数,用逗号 ,
分隔;表达式是函数体,只能是单个表达式,而不能是代码块。
举例:
lst = [(1, 3), (2, 1), (3, 2)]
sorted_lst = sorted(lst, key=lambda x: -x[1])
print(sorted_lst) # 输出 [(1, 3), (3, 2), (2, 1)]
其中,key=lambda x: -x[1]
表示将 x
中的元素按照第二个元素(x[1]
)进行取反(-
),用于实现降序排序。
明白了吧,那么本代码中的lambda x: (-x[1], x[0])像这种两个参数的是什么意思呢:
lambda x: (-x[1], x[0]) 中的 x 代表一个函数的参数,这里是一个元组。其中元组中第一个元素是字母出现的次数,第二个元素是字母本身。
lambda 表达式将元组作为输入,然后返回一个新的元组作为排序的关键字。
这个新的元组包含了两个元素,第一个元素是原来的字母出现次数的负数,第二个元素是原来的字母本身。
这样做的原因是希望在对字母出现次数进行降序排列时,当字母出现次数相同时,按照字母表顺序排序,即在字母出现次数相等时,使用字母本身作为第二关键字进行排序。
不要关注我,关注的都拉黑,不喜欢被关注捏!3Q
—快乐的小马