出处:http://blog.csdn.net/u010454729/article/details/48197229
preface: 在使用python的路上,总会遇到各种问题,各种trick,正如《Effective Python:编写高质量Python代码的59个有效方法》、《编写高质量代码——改善Python编程的91个建议》,以下也是自己在路上不断积累并且觉得有用的trick。
1.字典的get()函数:
D.get(k[,d]):若k在字典D中,则为其原来的value,否则默认为d。
在以往的项目中,多次遇到需要统计字符频率并且将其放到字典中,当时用上for及if等函数多行代码,略麻烦。
Figure2-1: 字典的get()函数
2.numpy包中tile()函数:
用于重复数组。
Figure2-2: tile()函数
3.listdir, glob取文件夹下的所有文件:
遍历文件夹下的文件,并以返回以 文件名为字符串的list。而不必使用os.walk遍历。结合isfile()函数,取文件,而非文件夹;结合isdir()取文件夹。
另外glob.glob()函数也能实现取文件夹下的文件。
Figure2-3: lisdir()
Figure 2-4: 结合isfile()
Figure 2-5: glob包
4.列表的append()函数与extend()函数:
append()将括号里面的参数的值作为整体,追加到原来的列表之中。
extend()将括号里面的参数的迭代值一个一个地追加到原来的列表中。不必用for遍历参数列表中的值并多次调用append()函数,直接用extend()搞定。
Figure3-1: append()函数与extend()函数
5.pickle模块序列化对象:
python的pickle模块实现了基本的数据序列和反序列化。通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储;通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。并且使用cPickle效果更好,import cPickle as pickle即可。
在《机器学习实战》3.3.2决策树的存储中用到:
- import pickle
- def storeTree(inputTree, filename):
- fw = open(filename, ”w”)
- pickle.dump(inputTree, fw)
- fw.close()
- def grabTree(filename):
- fr = open(filename)
- return pickle.load(fr)
import pickle def storeTree(inputTree, filename): fw = open(filename, "w") pickle.dump(inputTree, fw) fw.close() def grabTree(filename): fr = open(filename) return pickle.load(fr)
Figure3-2: pickle模块序列化对象测试
6.split(),enumerate, max, isinstance
- #coding:utf-8
- #——————-
- #split()的maxsplit()参数,第二个参数数值,代表着对前多少个分隔符进行分裂。
- print ‘hello,world,foo,bar’.split(‘,’,2)
- #[‘hello’, ‘world’, ‘foo,bar’]
- #——————-
- #当遍历的时候,用enumerate()同时获得元素和下标。第二个参数数值表示从该数值开始遍历。无则默认为0
- print list(enumerate([‘a’,‘b’,‘c’],2))
- #[(2, ‘a’), (3, ‘b’), (4, ‘c’)]
- #——————-
- #切片步长。[a:b:c],从a开始,b结束,每隔c个取一个,
- #a为默认为0,b默认为-1,即最后一个,c默认为步长1
- arr = [’a’,1,‘b’,2,‘c’,2]
- print arr[::3]
- print arr[1::2]
- #[‘a’, 2]
- #[1, 2, 2]
- #——————-
- #max()/min()
- arr2 = [(’a’,3),(‘b’,2),(‘c’,1)]
- print max(arr2)
- print max(arr2,key=lambda x:x[1])
- #找出元素为元组的列表最大的元素。若无参默认取根据元组第一个元素进行比较
- #使用lambda,以元组第二个参数作为比较对象
- #(‘c’, 1)
- #(‘a’, 3)
- #——————-
- #isintance()第二个参数可为元组,可以简化形如if isinstance(123.2,int) or isinstance(123.2,float)之类的
- print isinstance(123,int)
- print isinstance(123.2,(int,float))
- #True
- #True
- #——————-
#coding:utf-8
#------------------- #split()的maxsplit()参数,第二个参数数值,代表着对前多少个分隔符进行分裂。 print 'hello,world,foo,bar'.split(',',2) #['hello', 'world', 'foo,bar'] #------------------- #当遍历的时候,用enumerate()同时获得元素和下标。第二个参数数值表示从该数值开始遍历。无则默认为0 print list(enumerate(['a','b','c'],2)) #[(2, 'a'), (3, 'b'), (4, 'c')] #------------------- #切片步长。[a:b:c],从a开始,b结束,每隔c个取一个, #a为默认为0,b默认为-1,即最后一个,c默认为步长1 arr = ['a',1,'b',2,'c',2] print arr[::3] print arr[1::2] #['a', 2] #[1, 2, 2] #------------------- #max()/min() arr2 = [('a',3),('b',2),('c',1)] print max(arr2) print max(arr2,key=lambda x:x[1]) #找出元素为元组的列表最大的元素。若无参默认取根据元组第一个元素进行比较 #使用lambda,以元组第二个参数作为比较对象 #('c', 1) #('a', 3) #------------------- #isintance()第二个参数可为元组,可以简化形如if isinstance(123.2,int) or isinstance(123.2,float)之类的 print isinstance(123,int) print isinstance(123.2,(int,float)) #True #True #-------------------
7.逗号的作用:
这里介绍的不是print后面加个逗号不换行,逗号将变量变成元组这样的技巧。而是能够作为list追加的功能。最近在刷leetcode,也参考了些别人的代码,没想到自己以前居然没注意到这个功能,太low了。上代码先(坑爹呢,在windows下传不了图片):
- In [11]: a = range(10);print a;a+=20;print a
- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- —————————————————-
- TypeError Traceback
- <ipython-input-11-1ecec217dce6> in <module>()
- —-> 1 a = range(10);print a;a+=20;print a
- TypeError: ’int’ object is not iterable
- In [12]: a = range(10);print a;a+=20,;print a
- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20]
- In [13]: a.append(0)
- In [14]: a
- Out[14]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 0]
- In [15]: a[-1]=21
- In [16]: a
- Out[16]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 21]
- In [17]:
In [11]: a = range(10);print a;a+=20;print a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
TypeError Traceback
<ipython-input-11-1ecec217dce6> in <module>()
—-> 1 a = range(10);print a;a+=20;print a
TypeError: ‘int’ object is not iterable
In [12]: a = range(10);print a;a+=20,;print a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20]
In [13]: a.append(0)
In [14]: a
Out[14]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 0]
In [15]: a[-1]=21
In [16]: a
Out[16]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 21]
In [17]:
a作为一个列表,不能用加号直接添加元素,需要加个逗号才行。如同在最后面追加一个元素,然后改变最后一个元素的值是一个道理。
8.使用列表相乘(2016.4.13):
卤煮最近做算法题,需要构造同样大小的矩阵,如做dp动态规划的题的时候需要构造个dp矩阵,以前卤煮用两次for+range,却没想到可以用[]+*,故记录下来。
Figure 7: 列表相乘
2016.4.14更新:
上述做法有错误,在外层循环不可乘col,因为列表的可变特性,导致更改某个元素的时候,该列的所有元素也都为改后的元素,非我本意。在外层循环中还是需要使用for。以下代码的变化可以看出端倪。
9.数据结构collections:
python有自己的数据结构,collections里面的几个,比较有帮助。
官方文档:https://docs.python.org/2/library/collections.html#module-collections
10.python的几个内置函数:
参考鹏哥的开源中国博客:python基础——内建函数
lambda(),map(),reduce(),filter()
map():
reduce(func, seq[, init]):
二元操作函数,将一个数据集合中的所有数据进行下列操作:对seq中的第1,2个数据传入func进行操作,得到的结果,再与seq中的第3个元素用func函数继续运算,迭代直到所有元素运算完成。第3个可选参数init作为第一次迭代的第一个元素使用。若是seq长度为1,则传入func中的第1,2个元素都为seq中的该元素。init效用可参考:python函数式编程——map()、reduce()
func必须是二元操作符运算。
filter():
11.list列表n+1维变n维
使用sum(mat, [])。另外可使用逗号或者extend。sum(mat, [])看起来很优雅,但使用平方级的运行时间,使用extend会是更好的选择,当超过某个长度,sum(mat, [])会完败。《python算法教程》P38
- a = [[1,2],[3,4]]
- b = []
- for i in a:
- b+=i
a = [[1,2],[3,4]] b = [] for i in a: b+=i
对应的将n维转为n+1维:
numpy里面有reshape比较方便。但对于普通的比如说一维数组,化为二维数组。?
12. 使用min(max())限制取值范围
若是value大于a取a,小于b取b,在[a,b]之间,不变,那么可以通过min(max(b, value), a)来限制其在[a, b]之间:
- min(max(-2147483648,result),2147483647)#限制结果的范围
min(max(-2147483648,result),2147483647)#限制结果的范围
13.random包选择随机数神器
因为任务需要,经常需要随机划分数据集为训练集和测试集,使用sklearn自带的cross_validation.train_test_split()函数满足不了任务需求,因为需要根据每类等同比例取数据,使用cross_validation.StratifiedKFold()也不够,当需要划分为训练集、测试集、验证集三种时,结果挺凌乱的,还是自己弄的好,有些工具类的若是不明了工作原理,还是慎用,不然漏洞百出,做的实验不合理。
random包下挺多函数的,但常用choice、random、Sample这几个函数。
14.key-value互换:
另外在知乎里面:
也有挺多技巧的
15.eval
将列表、元组、字典型等字符串转为列表、元组、字典等:
还有个用处是将数学表达式字符串直接转化为表达式计算后的结果,若是数学表达式符合规范。
另外可用ast.literal_eval()代替eval(),其能获得更好的性能。
16.重复字符串满足循环替换
什么意思呢?比如说有个加密字符串,对其里面每个英文小写字母a到z,想要将字母向后移动两个f(x) = x+2进行解密,那么直接使用alpha = string.lowercase; alpha+=alpha; new_string += alpha[alpha.index(i)+2]就可以了,而不需要单独针对y和z字母进行判断。在《剑指offer》里面也有相应的技巧说明。
17.pdb模块设置断点
使用python的时候,以往卤煮经常使用raise大法设置断点,print大法在raise前面找到问题所在,这种方式对于小规模程序没啥问题,但是对于大规模程序需要调试的时候,却很low。学会调试断点使用spyder观察各变量的值还是很有必要的。
然而在默认包里面没有pdb的介绍,资料可以参考pdb官网。
参考伯乐头条里面初学者必知的python中优雅的用法,其它类似pprint优雅的打印、enumerate枚举、三元运算等操作《python cookbook》里面包含更多,可以在cookbook里面看到更为详细的介绍。
18.pow(a, b, c)
常用pow()函数,但第三个参数却不常用。
pow(a, b, c)等同于pow(a, b)%c,即a**b%c,也即a的b次方,对c取余。并且pow(a, b, c)效率最高。
待续:
长期更新。。。