一个文章单词分析作业

 题目:通过python分析给定文件中小说(群共享文件 emma.txt)的单词直方图(单词,频率) 
分析:

第一步先把文件读进来,简单的文件操作;

第二步把文本按照单词打散,可以通过str.split循环对各个标点进行切分,但是感觉这么做好low,耗时,耗内存,还会产生很多多余的空字符,在后期需要排除,另外像名字后带's这样的单词不好处理,只能暂时先分割成两个单词;

第三步相同的单词合并,计数+1,用字典可以很简单的处理;

第四步根据统计画图,画图还没学,暂时考虑先按照出现次数排序,再打印出来。

1.读文件

with open('emma.txt') as f:
    text = f.read()

2.把文章打散

最初是这么做的,每发现一个特殊字符,就手动添加一段代码,劳神费力

l1 = text.split('.')
print(len(l1))
l2 = []
for i in l1:
    l2 += i.split(',')
print(len(l2))
l3 = []
for i in l2:
    l3 += i.split('\n')
print(len(l3))

既然代码基本是一样的,那么就考虑用循环来合并

last_list = [text]
split_str = '''.,'" \n;-_?![]()`:'''
for x in split_str:
    new_list = []
    for i in last_list:
        new_list += i.split(x)
    last_list = new_list

每次发现新的特殊字符,在split_str中添加一个元素即可

3.计数

因为分割产生了很多空字符串'',所以在循环里面排除掉(实测空字符串高达4W多个)

di = {}
for i in last_list :
    if i=="":
        continue
    elif i in di:
        di[i] += 1
    else:
        di[i] = 1
print("len(di):",len(di))

4.排序

由于sort方法只能对key进行排序,所以这里的方法是从原字典中找出最大的元素,插入到新字典中,完成排序

di2 = {}
while len(di)>0:
    j=0
    for i in di:
        if j==0 :
            j = i
        elif di[i]>di[j]:
            j = i
        di2[j] = di.pop(j)


print("len(di2):",len(di2))

js = json.dumps(di2,indent=1)
print(js)

因为一共有7000多个元素,排序操作非常耗时


优化方案:

第二步文章打散,用正则匹配,耗时的双重循环操作瞬间出结果,同时,不会出现空字符串,第三步的排除空字符串的操作也可以去掉了

last_list = re.findall("[a-zA-Z0-9]+", text)

第三步,用get方法取代if判断

di = {}
for i in last_list :
    di[i] = di.get(i, 0) + 1
print("len(di):",len(di))

第四步排序,调换key和value放到列表中,使用sort方法进行排序

di2 = {}
t = []
for key, value in di.items():
    t.append((value, key))
t.sort(reverse=True)
for i in t:
    di2[i[1]]=i[0]

瞬间排好,效率大增

第一步读取文件可以考虑按行读取,节省内存,但是后面需要改动较大,这里就暂不修改了


总结:
如果可以的话,尽量不要在python中写任何可能耗时的算法,能用库函数解决的就用库函数解决
原文地址:https://www.cnblogs.com/ikamu/p/8299695.html