最近看一篇论文的源码,正巧是用python写的,看的我羞愧难当...
因为是从今年暑假才开始自学python,写的经验不够多,每次的代码都很冗余。看看大佬,各种包和特殊语法用的得心应手,看来我还需要多看多编才能进阶..
1.python是一门面向对象语言
我几乎是忽略了它这个特性,从未创建过class,把代码几乎写成了面向过程的样子。不过,值得注意的是python中一切皆为对象。
如果自己自定义一个类,__init__函数就是构造函数,前面加了下划线的函数是私有函数,但不同的是python的类中函数都在第一位多一个self参数。
有一个包pickle专门做对象序列化,dump方法序列化对象,将对象保存到文件file中去,还有个反序列化方法
类方法
class Solution:
def A(self,a):
...
def B(self,b):
self.A(a) #此处要用self调用
2.python有很多特有语法或函数
简洁写法:
lines = [line.rstrip() for line in edges_file]
建立二维列表/数组
list1 = [[0]*2 for i in range(3)]
with as:适合事先需要设置,事后做清理工作的任务,譬如读写文件
file = open("/tmp/foo.txt")
data = file.read()
file.close()
先打开了再读,读后还要关闭,这三步可以简化为(自动关闭了)
with open("/tmp/foo.txt") as file:
data = file.read()
enumerate:
for i in range(test_list):
l = test_list(i)
i = i+1
可以优化为:
for i, l in enumerate(test_list):
i = i+1
yield:到yield就会中断,每次中断都会返回当前的迭代值。有效yield这个生成器工具可以避免不必要的内存占用。
for line in corpus:
yield list(tokenize(line,lowercase=False))
join: 'sep'.join(字符串、元组、字典),返回一个以分隔符sep连接各个元素后生成的字符串
>>> import os
>>> os.path.join('/hello/','good/boy/','doiido')
'/hello/good/boy/doiido'
zip:用于将可迭代对象(字符串、列表、元祖、字典)作为参数,将对象中对应的元素打包成一个个元组
利用 * 号操作符,与zip相反,进行解压。具体用法参照此篇博客
#计算向量点积
dot_res = sum([i*j for i,j in zip(list1,list2)])
map:它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。
xrange:list(xrange(start, stop[, step]))
sorted:sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作
argsort:numpy里面用来排序,可通过axis指定行列
eval:用来执行一个字符串表达式,并返回表达式的值。
strip:strip用来移除字符串头尾指定的字符(默认为空格或换行符),lstrip用来去除开头字符,rstrip用来去除结尾字符
list:list中根据索引删除用del,根据元素删除用remove
集合取并集、交集、差集等
l1 = [1,2,4]
l2 = [1,2,3]
l3 = [1,2,5]
print set(l1) | set(l2) | set(l3)
print set(l1) & set(l2)
print set(l1) - set(l2)
python中的除法:
#python 3中/得到浮点数,//得到整数,2中两者都得到整数
#python2要进行精确除法必须from __future__ import division
如果要在python3中正常使用
3.python有很多包的API很好用
collections包里的defaultdict,譬如senses_num = defaultdict(int),当所访问的键不存在的时候,可以实例化一个值作为默认值。譬如这里可以默认为0,方便计数。
collections包里的Counter,可以进行计数,形成字典,value为出现次数
count = Counter(words)
dic = dict(count)
#对字典按value排序
dic = sorted(dic.items(),key=lambda item:item[1],reverse=True)
codecs包:with codecs.open(corpus, 'r', encoding='utf-8') as input,可以指定一个编码打开文件,避免乱码问题
4.python2与python3的区别
(1)输出 这个真的很烦,python3必须是print加()
(2)python3的dict_keys不像python2那样支持通过索引来访问,只能通过迭代器
解法方案:将keys强制转换为list
5.python文件读写
这个我一向感到迷糊,在此总结一下
(1)读文件
read/readlines/readline
- read() 每次读取整个文件,它通常用于将文件内容放到一个字符串变量中。如果文件大于可用内存,为了保险起见,可以反复调用
read(size)
方法,每次最多读取size个字节的内容。 - readlines() 自动将文件内容分析成一个行的列表,该列表可以由 Python 的 for ... in ... 结构进行处理。
- readline() 每次只读取一行,通常比readlines() 慢得多。仅当没有足够内存可以一次读取整个文件时,才应该使用readline。
- 注意:这三种方法是把每行末尾的'\n'也读进来了,它并不会默认的把'\n'去掉,需要我们手动去掉(strip)
read_csv:将整体的CSV文件存储为数据框对象
from pandas import read_csv
df = read_csv(path, encoding='utf-8', delimiter=',')
loadtxt:numpy.loadtxt(file_path,dtype='int',delimiter=' '):将数据读出为array类型
(2)写文件
write/writelines:writelines接收一个字符串列表作为参数,将他们写入到文件中,换行符不会自动的加入,因此,需要显式的加入换行符。
to_csv:dataframe.to_csv:跟前面的read_csv相对应,将数据框对象写入CSV文件
savetxt:numpy.savetxt(file_path,fmt='%f',delimiter=' ',skiprows=2,comment=‘#’,unpack=True)
将array保存到txt文件,并保持原格式。其中,skiprows为跳过前两行,comment是指定注释符号, 如果行的开头为#就会跳过该行,unpack=True是指
会把每一列当成一个向量输出, 而不是合并在一起
6.nltk库进行文本预处理
#nltk库
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
from nltk.tokenize import sent_tokenize
from nltk.stem.lancaster import LancasterStemmer
from nltk.stem.porter import PorterStemmer
from nltk.stem.wordnet import WordNetLemmatizer
from nltk import pos_tag,ne_chunk
path = ""
with codecs.open(path, "r",encoding="ISO-8859-1") as input:
text = input.read()
text = text.lower() #1.转换为小写
#2.在此处做分句
sentences = sent_tokenize(text)
print sentences[0:3]
#还可以对句子做语法解析
#3.做分词和词性标注
words = word_tokenize(text)
tagged = pos_tag(words) #参数必须传分词后的token序列,而不能是str
entities = ne_chunk(tagged[0:10]) #参数必须传标注后的序列
print entities
#4.去掉停用词
stop_words = set(stopwords.words('english'))
words = [word for word in words if word not in stop_words]
#5.1 词形还原,例如复数->单数
lemmed = WordNetLemmatizer()
words = [lemmed.lemmatize(word) for word in words]
#5.2 词干化
#有多种词干化方法供选择,但经常不能提取出完整的词干
st1 = PorterStemmer()
st2 = LancasterStemmer()
words = [st1.stem(word) for word in words]