本帖最后由 梁强 于 2018-8-28 11:02 编辑
题目:统计一个文件中每个单词出现的次数,列出出现频率最多的5个单词。 前言:这道题在实际应用场景中使用比较广泛,比如统计历年来四六级考试中出现的高频词汇,记得李笑来就利用他的编程技能出版过一本背单词的畅销书,就是根据词频来记单词,深受学生喜欢。这就是一个把编程技能用来解决实际问题的典型场景。另外,在数据分析时,那些词云效果本质上都是基于词频统计来调整字体的大小,如果你能熟练运用Python中的知识来解决问题的话,说明你真的入门Python了。 分析本题主要考察以下几个方面的知识点: 1、如何正确读写文件 在python中读写文件可以使用内置函数open(),而 open 函数在python2 和 python3 中有一定的区别,比如 Python 中可以指定读写文件的编码格式,而 Python 则不可以,为了同时兼容2和3,我们通常会使用io模块下面的 open 函数,大家可以查文档搞清楚它们之间的区别,培养主动学习能力和查资料的习惯。 另外一点是读写文件完成之后是需要关闭文件描述符的,除了可以使用 try...except...finally的语法之后,我们还可以使用更优雅的 with … as 的语法来自动关闭文件。 2、如何对数据进行排序 sorted函数是一个使用频率很高的内置函数,它的用法也很强大,因为它可以通过指定参数 key 来进行自定义排序,也就意味着你不仅可以对数字排序、对字母排序、还可以对列表、字典、自定义的对象进行排序,你只需要要告诉 sorted 函数的排序规则是什么,比如一个people对象,我既可以根据年龄排序也可以根据身高体重来排序,所以这个函数时非常灵活的,另外,对于列表对象有自带的 sort 方法,如果能区分清楚 list.sort 与 sorted 之间区别那说明你已经能灵活运用了。 3、字典数据类型的运用 4、正则表达式的运用 实现分析完之后,我们实现起来其实是非常快的。所以我们在拿到一个需求的时候,首先肯定是把需求弄清楚,想想大概可以用哪些技术来实现,随后才是动手写代码,其实我们在工作上,真正写代码的时间还不到一半。 [Python] 纯文本查看 复制代码 # -*- coding:utf-8 -*-
import io
import re
class Counter:
def __init__(self, path):
"""
:param path: 文件路径
"""
self.mapping = dict()
with io.open(path, encoding="utf-8") as f:
data = f.read()
words = [s.lower() for s in re.findall("\w+", data)]
for word in words:
self.mapping[word] = self.mapping.get(word, 0) + 1
def most_common(self, n):
assert n > 0, "n should be large than 0"
return sorted(self.mapping.items(), key=lambda item: item[1], reverse=True)[:n]
if __name__ == '__main__':
most_common_5 = Counter("importthis.txt").most_common(5)
for item in most_common_5:
print(item) 打印结果: [Python] 纯文本查看 复制代码 ('is', 10)
('better', 8)
('than', 8)
('the', 6)
('to', 5)
总结我在看大家代码的时候,很多代码依然存在有命名不规范(建议读PEP8),代码的排版混乱(阅读起来很困难,建议用Pycharm进行格式化)。还有不少代码的实现方式看起来很复杂(往往越复杂的代码Bug越多)。当然,实现方法不是唯一。 比如Python模块本身就提供了一个collections.Counter的类,它继承自dict类,就是用于做统计的,我发现有部分同学使用的就是这个类来实现的,细心的你可能发现了,我实现的这个Counter和collections下面那个Counter很像,其实这就是造轮子,造轮子可以锻炼我们的编程思维,当然在工作上有现成的东西就没必要自己造轮子了,除非你有信心做得更好。你也可以思考思考,假如Python没有提供Counter这个工具,你该怎么做。 另外,该模块还提供一个有序的字典对象 OrderedDict,使用它可以免去我们手动排序的操作。最后建议大家学习总结上面我提到的所有内容。如果你能坚持100天,相信你对Python的掌握程度是游刃有余的。 |