最近在上课时遇到了一个有意思的问题,题目如下:
用python统计一段字符串中出现次数最多的20个字(词,选做),并输出其出现的频率
字符串的内容为:
“语言是人类区别其他动物的本质特性。在所有生物中,只有人类才具有语言能力。人类的多种智能都与语言有着密切的关系。人类的逻辑思维以语言为形式,人类的绝大部分知识也是以语言文字的形式记载和流传下来的。因而,它也是人工智能的一个重要,甚至核心部分。用自然语言与计算机进行通信,这是人们长期以来所追求的。因为它既有明显的实际意义,同时也有重要的理论意义:人们可以用自己最习惯的语言来使用计算机,而无需再花大量的时间和精力去学习不很自然和习惯的各种计算机语言;人们也可通过它进一步了解人类的语言能力和智能的机制。实现人机间自然语言通信意味着要使计算机既能理解自然语言文本的意义,也能以自然语言文本来表达给定的意图、思想等。前者称为自然语言理解,后者称为自然语言生成。因此,自然语言处理大体包括了自然语言理解和自然语言生成两个部分。历史上对自然语言理解研究得较多,而对自然语言生成研究得较少。但这种状况已有所改变。”
我看到这题第一个想法是利用字典对出现次数进行统计,随后使用排序来筛选得到前20个单词
这里唯一值得注意的就是对于中文的判断
关键点:
1,判断字符是否为中文
2,利用字典统计出现次数
3,排序得到前20单词
def find_words_count(sentence:str)->list:
"""
找到句子中出现次数排前20的中文
:param sentence: 句子
:return: 出现次数排前20的中文
"""
ch_dict={}
for char in sentence:
if '\u4e00'<=char<='\u9fa5':
if char in ch_dict:
ch_dict[char]+=1
else:
ch_dict[char]=1
sorted_ch_dict=sorted(ch_dict.items(),key=lambda x:x[1],reverse=True)
return sorted_ch_dict[:20]
然而,对于中文可以这样判断,英文就不太行了,总不能去统计出现最多的英文字母吧?一般都是统计出现的英文单词的数量,这时候,就有一些预处理需要注意了。
需要注意的预处理步骤有如下几点:
1,要对字符串前后去空格
2,当使用空格分割字符串之后,需要去除单词前后的符号,如,!.等
3,在去除了符号之后,需要对所得单词统一变为大写或者小写,以避免统计失误。
4,最后还需判断所得单词是否全为英文构成,有时中间会参杂着数字
def find_words_count_english(sentence:str)->list:
"""
找到句子中出现次数排前20的英语单词
:param sentence: 输入的句子
:return: 返回一个列表,包含20个元组
"""
en_dict={}
for word in sentence.split():
en_word=word.strip(string.punctuation).lower()
if en_word.isalpha():
if en_word in en_dict:
en_dict[en_word]+=1
else:
en_dict[en_word]=1
sorted_en_dict=sorted(en_dict.items(),key=lambda x:x[1],reverse=True)
return sorted_en_dict[:20]
然而,上述方法只能统计单词或者汉字,那如果要统计指定的词语呢?这是可能需要用到正则模块re
def find_sentences_count(sentences:str,temp:str)->int:
"""
找到指定词语在句子中出现的频率
:param sentence: 输入的句子
:return: 返回一个整数,代表出现的次数
"""
count=0
list_result=re.findall(temp,sentences)
count=len(list_result)
return count
接下来是一些常用的re模块使用方法以及正则表达式表示方法。
#re.match(pattern,string)使用
result=re.match(r'hellow','hellow world')
最后会输出hellow
#re.findall(pattern,string)查找所有非重叠匹配项
url=re.findall(r'https?\\[\S]+',string)
#re.search(pattern,string) 搜寻第一个匹配的项目并返回match对象,与match不同,其只会搜到匹配的第一个项目
#re.sub(pattern,replace,string)其中pattern为要替换的对象,replace为替换后的字符,string 为所操作的字符串对象
result=re.sub(r'[^0-9a-zA-Z\s\u4e00-\u9fa5]','',string) 使用sub方法去除字符串中的特殊字符
所有的re模块函数返回对象均为match类型
match类型有以下方法:
start,group,end,span
group()在默认情况下返回match所有分组的字符串,当有指定时则返回指定字符串
start([group])即返回指定分组的起始点
end([group])即返回指定分组的终点
span([group])即返回一个元组,包含指定元组的起点与终点




这个背景颜色是真难搞(ฅ´ω`ฅ)