问题
假设你是小蔡,你和小徐同学一起穿越到了抗战时期,分别成为了八路军华北根据地A地和B地的联络员。此时,两地的八路军部队准备发动协同进攻,给予日寇重重一击。由于某些原因无法亲自送信,为了约定进攻时间,小徐只能通过伪军的邮政系统寄送密信。信上的信息看起来平平无奇(如666.txt所示),只有若干行文字……直到你看到了正文最后一段文字: “小蔡,还记得咱上Python课的时候,学的词频统计吗?咱当时只会统计前四个词,还没学其他的。我相信,我们最终一定能回到和平幸福的新时代,那时我们会重逢的,勿念。” 现在,你收到了这封密信,发现自己带过去的笔记本电脑还有电。请根据所学的词频统计知识,使用jieba库编写程序,统计信中各个词语的词频并按词频降序排列词语;之后找出规律,以字符串形式输出秘密情报的关键内容,获得发动进攻的时间信息。
信的内容如下(放在一个名为666的文本里面):
小蔡啊:
好久不见!不知道你过得怎么样,还好当时有所准备,我带过来的东西,除了钱,除了手机,除了充电器,除了银行卡,除了校园卡,除了笔记本,都还能用。
我还记得咱们离开那个世界时,天边还是夕阳,穿越的那个地方有点偏,周围没有一个行人,连动物都没有,不知道动物们去哪了。可能是夕阳告诉动物们,该休息了吧。
我给你写这个信的时候,周围行人还挺多的,但是行人都忙着逃荒,在夕阳下显得有点伤感。每一次看到夕阳,每一次行人走过,我都希望看到你出现。在这个年代,不晓得还有几次看见夕阳的机会。
小蔡,还记得咱上Python课的时候,学的词频统计吗?咱当时只会统计前四个词,还没学其他的。我相信,我们最终一定能回到和平幸福的新时代,那时我们会重逢的,勿念。
解析
首先打开那个文件并且读取,用jieba库的lcut()方法进行精确模式切分中文词语,这个方法会将切分好的词语作为列表类型返回,然后再进行词语的计数并且降序输出,最后再查找规律
1,打开文件
这里直接用with的方式打开文件:
import jieba
import codecs
wenjian=input("输入文件路径:\n")
with codecs.open(wenjian,'r+','utf-8')as fp:
a=fp.read()
b=jieba.lcut(a)
输入方式是输入一个文件的一个路径
你们可以存放在这个项目里面,到时候就直接输入666.txt好了
如果用codecs这个库,再加上with的方式来打开文件,就不再用close()的方式去关闭文件,执行过后会自动关闭,并且大大提高安全性,你也可以用io这个库,不过可能会出一点问题,为了方便我就直接用codecs了
然后就是a接收文件里面的内容,b就接收把a切分好的列表类型数据
2.除杂并且计数
去掉一些不必要的字符,比如单个字符和一些符号:
d = {} # 定义一个空字典
for i in b:
if i == '\r\n':
continue #因为该文件夹有大量\r\n,需要清理掉
if len(i)==1:
continue
else:
d[i] = b.count(i)#count是一个计数方法
在除杂的时候,可以进行一些计数操作,count()这个方法就是来计数的,还有d是一个字典类型,规则是这样的:{<键>:<值>},其中类似下标的,就是键,用键来存储数据,而另外的值,就是储存计数。 如上面的 d[i] = b.count(i) ,i是b里面的一个数据,用这个方法会统计b里面全部跟 i 相同的数据,然后统计完再赋值给键为 i 的字典,此时字典就是{<i>:<为i的计数>}
这样除杂的时候顺便也统计了,下一步就是排序
3.排序
items=list(d.items())#列表化
items.sort(key=lambda x:x[1], reverse=True)#x:x[1]以第二个元素排序,x:x[0]以第一个元素排序
item()方法把字典中每对key和value组成一个元组,可以把它转化为列表类型,再用sort()方法进行排序,因为sort()是列表类型的,所以转换类型很有必要
key=lamda x:x[1]这个的意思是以值作为排序标准,也就是文中的计数大小作为标准,reverse接受的是一个bool类型的值 (Ture or False),表示降序还是升序,一般默认的是False,也就是升序,注意第一个字母是大写的
排序完,就是输出了
4.输出
i=0
while i<len(items): # 遍历
key,count=items[i]
print("{0:<10}{1:>5}".format(key, count))
i=i+1
因为item一个下标是储存着两个数据的,所以 key,count=items[i],key就是那个键,count也就是那个数量
还是很好理解的,输出就是这个了
除了 6
夕阳 5
行人 4
动物 3
知道 2
当时 2
记得 2
那个 2
有点 2
周围 2
没有 2
这个 2
时候 2
一次 2
看到 2
统计 2
我们 2
好久不见 1
怎么样 1
还好 1
有所准备 1
我带 1
过来 1
东西 1
手机 1
充电器 1
银行卡 1
校园卡 1
笔记本 1
咱们 1
离开 1
世界 1
天边 1
还是 1
穿越 1
地方 1
一个 1
可能 1
告诉 1
休息 1
但是 1
逃荒 1
显得 1
伤感 1
走过 1
希望 1
出现 1
年代 1
晓得 1
还有 1
几次 1
看见 1
机会 1
咱上 1
Python 1
词频 1
只会 1
四个 1
没学 1
其他 1
相信 1
最终 1
一定 1
回到 1
和平 1
幸福 1
时代 1
那时 1
重逢 1
勿念 1
附上源代码(该源码不是题目答案,下面最终代码才是):
import jieba
import codecs
wenjian=input("输入文件路径:\n")
with codecs.open(wenjian,'r+','utf-8')as fp:
a=fp.read()
b=jieba.lcut(a)
d = {} # 定义一个空字典
for i in b: #
if i == '\r\n':
continue #因为该文件夹有大量\r\n,需要清理掉
if len(i)==1:
continue
else:
d[i] = b.count(i)#count是一个计数方法
items=list(d.items())#列表化
items.sort(key=lambda x:x[1], reverse=True)#x:x[1]以第二个元素排序,x:x[0]以第一个元素排序
i=0
while i<len(items): # 遍历
key,count=items[i]
print("{0:<10}{1:>5}".format(key, count))
i=i+1
5.查找线索规律:
规律大概是这样,最后一句话有提示,说咱们只会统计前四个词,我们可以输出一下最初四个词是这样的:
'小', '蔡', '啊', ':', '\r\n', ' ', ' ', ' ', ' ', '好久不见', '!', '不', '知道', '你', '过', '得', '怎么样', ',', '还好'
这是我截取的前四个词语,当然单个字和符号不算,我们往上去找那个全部输出,可以发现
'好久不见' 为1, '知道' 为 2, '怎么样' 为1, '还好' 为1,再将其进行倒序
显然是2111
结合起来应该是21:11,这样的时间就非常合理,夜袭嘛
所以最终代码如下(只需统计前四个词的数量):
import jieba
import codecs
wenjian=input("输入文件路径:\n")
with codecs.open(wenjian,'r+','utf-8')as fp:
a=fp.read()
b=jieba.lcut(a)
d = {} # 定义一个空字典
p=0#记录储存了多少个数
for i in b: #
if i == '\r\n':
continue #因为该文件夹有大量\r\n,需要清理掉
if len(i)==1:
continue
else:
d[i] = b.count(i)#count是一个计数方法
p=p+1
if p==4:#只储存前四个词的计数
break
items=list(d.items())#列表化
items.sort(key=lambda x:x[1], reverse=True)#x:x[1]以第二个元素排序,x:x[0]以第一个元素排序
i=0
shijian=''
while i<p:
key,count=items[i]#将count提取出来并组成新的列表
shijian=shijian+str(count)#字符串间可以直接加,来组成新的字符串
i=i+1
print(shijian)
改的不是很多,你们可以对比一下两个代码就知道了
最后,为什么发两个代码呢?
第二个代码只能解答这种特定的问题,然而第一个代码却可以解答更多类似的问题
希望各位能通过我的两个代码能学到比只有第二个代码更多的知识
有用不妨点个免费的赞吧~~