文件读取写入
f = open('文件路径','r') # 'w''r''wr'等都是决定是以写、读、读写方式打开文件
f.close() # 用open打开文件的话必须记得close,因为对文件的读写都不是马上完成的,用close相当于提醒python赶紧干活然后结束
with open('path') as f: # 使用with就免去了close,在with结束后自动close
对f的处理
with fileinput.input(files='path') as f: # 这里返回的是一个能返回文本每一行的迭代器
for line in f:
对每一行的处理
2017.12.15
补上一句
f.read(): 直接读取文件全部内容,str形式
f.readline():读取一行,str形式
f.readlines():读取所有行,列表形式,每一行都是列表的一个元素,元素是str形式
字符串处理
这部分东西好多看的头疼。。。。以下是我尝试过的
str = ‘ac4abc5bc’
str.strip('abc')
'''
这个只能用来去除首部和尾部的指定字符,注意是字符而不是字符串;然后按照这个str来看的话会把a去掉,然后发现首部还有c可以去除,然后是4,
不能去除,那么首部清除完成;然后尾部,c可以,b可以,5不行,所以最后剩下‘4abc5’
最后返回一个新的字符串‘4abc5’
'''
str.split(sep=None, maxsplit=-1)
将字符串中的sep字符取出,并在这儿将字符串分割开,最后返回一个列表
不输入sep参数的话默认是按空格分隔,maxsplit决定了分隔的次数,-1时不限次数
str.replace(old, new[count])
将字符串中与old相同的部分用new替换,count部分决定了替换次数,默认为最大次,最后返回一个新的字符串
string.punctuation
# 这个返回的是'!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~'
counter
counter提供了许多方便的计数功能,需要计数的时候都可以来看看collections库的官方文档,counter在8.3.2
官方文档中,counter是dict的一个子类,因此可以调用dict的方法。作为一个计数类,它允许value接受负值和0
counter有以下几种方法
Counter.element():按照键值,无序地将键返回,若键值为0则不返回对应的键
Counter.most_common(n):返回一个列表,其中是按照从大到小排列的counter中的键和键值,n决定的是返回前n个
Counter.subtract(iterable or mapping):对其进行c-d的减法
示例请看官方文档
正则表达式
# 常用的调用格式
pattern = re.compile('待匹配的正则表达式')
match = re.search(pattern,待匹配文本) #re.match和re.search都可以,主要区别在于match是从开头匹配,而search则是在文本任意部分匹配
# 匹配不成功的话会返回None,匹配成功则返回一个match对象
match.group() # 获取匹配文本
几种方法
nltk库的词频统计
用别人造好的轮子那是比较轻松了
import nltk
from nltk.corpus import stopwords
import fileinput
from nltk.tokenize import word_tokenize
class WordsFrequency:
def __init__(self, path):
self.path = path
def get_text(self):
with fileinput.input(files=self.path) as f:
words = []
for line in f:
words.append(line)
return words
def clean_text(self):
sr = stopwords.words('english') # 包含了英语中的一些诸如is、a之类无意义的词
clean_texts = list()
for sentence in self.get_text():
tokens = word_tokenize(sentence)
for token in tokens:
if token not in sr:
if token is not '.' and "'": # 去除标点符号
clean_texts.append(token)
return clean_texts
def nltk_method(self):
clean_tokens = self.clean_text()
freq = nltk.FreqDist(clean_tokens)
freq.plot(10, cumulative=False) # ‘10’用于说明要统计的是词频数前10的
利用matplotlib作图
首先,这是它的官方文档
import matplotlib.pyplot as plt
plt.plot(x, x, label='linear') # 一条以x为横轴,x为纵轴,标签为‘linear’的曲线
plt.plot(x, x**2, label='square')
plt.plot(x, x**3, label='cubic')
plt.xlabel('xlabel') # 给x轴添加标签‘xlabel’
plt.ylabel('ylabel')
plt.title('simple example') # 添加标题‘simple example’
plt.legend() # 在左上添加一个legend,显示三条曲线的表现和对应的颜色
plt.show() # 显示图片
个人认为以上是在作图过程中较为常用的几个命令,用于给图添加说明。
虽然最后放弃该方案作图了。。。不过还是稍微介绍了下直方图
这次的内容是词频统计,因此用直方图较为合适,用于表示数据的分布情况(可以想象成统计相同数据出现的次数)
matplotlib.pyplot.hist(x, bins=None, range=None, density=None, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, stacked=False, normed=None, hold=None, data=None, **kwargs)
'''
这是它的调用格式,越后面的参数用的越不频繁,有时候可以查询
x:序列或者是数组类型
‘’‘
最后是对python之禅的词频分析
import nltk
from nltk.corpus import stopwords
import fileinput
from nltk.tokenize import word_tokenize
import re
import collections
class WordsFrequency:
def __init__(self, path):
self.path = path
def get_text(self):
with fileinput.input(files=self.path) as f:
words = []
for line in f:
words.append(line)
return words
def clean_text(self):
sr = stopwords.words('english') # 包含了英语中的一些诸如is、a之类无意义的词
clean_texts = list()
pattern = re.compile('\W')
for sentence in self.get_text():
tokens = word_tokenize(sentence) # 用word_tokenize将句子分成了单词,但是句点等符号还在
for token in tokens:
if token not in sr:
match = re.search(pattern,token)
if not match: # 去除标点符号
clean_texts.append(token)
return clean_texts
def freq_dist(self):
freq = collections.Counter(self.clean_text())
return freq
def most_common(self, number): # 统计频率最高的n个
return self.freq_dist().most_common(number)
def nltk_method(self):
clean_tokens = self.clean_text()
freq = nltk.FreqDist(clean_tokens) # nltk库提供的词频统计
freq.plot(30, cumulative=False) # ‘10’用于说明要统计的是词频数前10的
sorted
一直对sorted如何指定参数key实现自定义排序,借此机会了解一下
看官方文档是个好习惯,真的,这是sorted的官方文档
这里还有一个官方的sorting how to
从一个可迭代对象的item中返回一个重新排序的list
sorted(iterable,[,key],[,reverse]):
iterable 是待排序的对象,reverse要为布尔值,决定正序和倒序;
key则是决定以什么作为排序的参考
sorted(counts_dict,key=lambda x:counts_dict[x],reverse=True)
# 以counts_dict中的counts_dict[x]即键值作为排序的参考
个人认为可以这样理解,sorted的排序依据是key中的操作对iterable中的元素逐个作用后得到的值,但并不是直接返回该值构成的序列,而是该值在iterable中所对应的值。
以下勉强算是一串实现sorted的粗略伪代码
List = [........]
List_sorted = list()
List_1 = dict()
List_1_cache = list()
key = func()
for element in List:
List_1_cache = func(element)
List_1[element] = func(element)
List_1_sorted = sorted(List_1_cache)
for element in List_1_sorted:
List_sorted.append(element)
关于我所不知道的list
在看这篇文章的时候来自星球中叶宪克的分享
其中的一句让我很困惑
counts_dict={index:words.count(index) for index in words_index} #其中的words.count()
这里的words是一个列表,因此查阅官方文档关于list的说明4.6.1
常用到的list操作.png列出了一些我并不知道的事情
list = [[]] * 3
lsit[0].append(3)
>>>[[3], [3], [3]]
'''创建时候并不是分别创建了3个[],而是将一个[]引用了三次来创建[[], [], []],因此对任意一个[]的改动会同时影响list中的所有元素
但是如果是list[0] = 1,则不会同时影响三个元素
list1[0].append(1)这样的话则是[[1], [1], [1]]
'''
list1 = [[None, None]] * 3
list1[0][0] = 1
>>>[[1, None], [1, None], [1, None]] # 真的是excuse me了
这里官方还是只提到了reference,解释的并不是很清楚。我自己的理解是list1[0][0] = 1 ,lsit[0].append(3)操作对象都是原先的[None, None]和[]这样的列表,而创建列表用的是他们的reference,因此导致了整个列表的元素改变;而在list[0] = 1中更改的对象实际是list列表中的第一个元素
验证:
我尝试通过id检查来确定我的想法(从python之禅学到的)
list1 = [[None] * 2] * 3
print(id(list1[0]), id(list1[1]), id(list1[2]))
>>>2146680370248 2146680370248 2146680370248 # 这三个元素真特么的一模一样啊
list1[0][0] = 1
print(id(list1[0]), id(list1[1]), id(list1[2]))
>>>2732429341896 2732429341896 2732429341896 #这是分几次运行的,id不同是正常的
list2 = [[]] * 3
list2[0].append(1)
print(id(list2[0]), id(list2[1]), id(list2[2]))
>>>2231677759304 2231677759304 2231677759304
list2[0] = 1
print(id(list2[0]), id(list2[1]), id(list2[2]))
>>>1442337568 2231677759304 2231677759304
print(id(1))
>>>1442337568 # list2[0]与1指向了同一个对象
list1[0] = 1这一步实际上是将list1的第一个元素指向1这个对象了,而list1[0].append(1)则是在list1[0]所指向的[]对象中添加了1这个元素,第一段代码则是将list1[0]指向的[None, None]的第一个元素指向了0,并没改变list1[0]指向的对象
文字描述可能不够清晰,大家可以看看Python之禅关于变量和赋值个人认为对于理解我所说的有一定意义
- list[n],当n为负数的时候,实际上是这样调用的list[len(list)+n];-0不是负数
- 使用list[i ;j ; k]的时候实际的index是i + n * k(n < (j - i) / k)
看军哥代码
# -*- 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)]
# re.findall(pattern, str):在匹配过程中不会发生对同一个字符多次匹配的状况,并且如果在首部和尾部匹配到了空格则会将其去除
for word in words:
self.mapping[word] = self.mapping.get(word, 0) + 1
# 这是一种常用的用于创建一个字典,其键值是键在word中出现的次数
# dict[key] = dict.get(key, default) + 1,get方法用来获取键值,参数key即键,default是表示在dict中若没有key这个键则创建一对以key为键、默认值为default的键值
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)
网友评论