##百分号的使用:
通常我们都是这样格式化字符串的:
print 'hello world programme by %s' % 'python'
但是如果格式化的字符串中有很多%s,那么程序的可读性就会依靠于%后面 的变量名起得是否好了。
这个时候有一种用dict来格式化的%,我觉得很有用,尤其是在记log的 时候,作为log的格式,可读性非常高。
代码如下:
#字符串
value = {'what': 'hello, world', 'language': 'python'}
print '%(what)s, %(language)s' % value
#也可以包含int的
value = {'name': 'jianpx', 'age': 23}
print '%(name)s 's age is %(age)i' % value
用两个元素之间有对应关系的list构造一个dict:
运用zip可以非常简单的实现:
names = ['jianpx', 'yue']
ages = [23, 40]
m = dict(zip(names,ages))
zip的使用可以help(zip)或者查看官方文档。
##交换两个值:
在其他语言可能要一个临时变量和三句话:
temp = a
a = b
b = temp
但是在python,一句就ok了,而且不需要临时变量:
a,b = b,a
右边的b,a 其实可以理解成一个tuple。
##数量多的字符串相连用join:
python字符串效率问题之一就是在连接字符串的时候使用‘+’号,例如 s = 's1' + 's2' + 's3' + ...+'sN'
,总共将N个字符串连接起来,但是使用+号的话,python需要申请N-1次内存空间,然后进行字符串拷贝。原因是字符串对象PyStringObject
在python当中是不可变对象,所以每当需要合并两个字符串的时候,就要重新申请一个新的内存空间(大小为两个字符串长度之和)来给这个合并之后的新字符串,然后进行拷贝。所以用+号效率非常低。建议在连接字符串的时候使用字符串本身的方法join(list)
,这个方法能提高效率,原因是它只是申请了一次内存空间,因为它可以遍历list中的元素计算出总共需要申请的内存空间的大小,一次申请完。所以上面的例子可以写成s = ''.join(['s1','s2',....,'sN'])
例子是:
#以前是这样写的
fruits = ['apple', 'banana']
result = ''
for f in fruits:
result += f
#现在可以这样:
fruits = ['apple', 'banana']
result = ''.join(fruits)
##判断一个key是否在一个dict里面:
以前很经常犯的一个mistake是这样做:
if key in dict_example:
do something
现在要这样写,就不用使用in操作了。
if dict_example.has_key(key):
do something
##去掉list中的重复元素:
old_list = [1,1,1,3,4]
new_list = list(set(old_list))
##判断元素是否在列表中
如果对没有重复元素的列表对象,要判断某个元素是否在列表里面的话,当这个列表很大的时候,用set会比list
的性能要好,因为对于list,本身允许重复元素存在,所以它不是用hash实现的,但是set不一样,它不允许重复元素,看了python源代码,从set的实现源码setobject.c 中查找key的函数
static setentry *
set_lookkey(PySetObject *so, PyObject *key, register long hash)
的接口可以看出它真的使用hash去实现的。
所以对于in操作,set的实现是计算这个元素的hash值然后判断,理论上可以达到O(1)
##读文件操作:
以前是这样写的:
#默认文件存在,不处理Exception的情况
f = open('filename', 'r')
while 1:
line = f.readline()
if not line:
break
print line
if f:
f.close()
用with关键字可以这样简写了,
from __future__ import with_statement
with open('filename','r') as f:
for line in f:
print line
具体关于with的可以参考这篇文章
##输出数组的index和值:
以前是要这样写的:
l = [1,3,4]
for i in xrange(len(l)):
print '%d, %d' % (i , l[i])
现在可以用enumerate函数帮助你简写:
l = [1,3, 4]
for index, value in enumerate(l):
print '%d, %d' % (index, value)
##关于使用map、filter、reduce的例子网上很多,这里不细说了,它们的使用也是pythonic的examples
##分隔一个字符串,去里面的元素,
,但是空白字符串不要:
例如, names = ‘jianpx, yy, mm, , kk’
names = 'jianpx, mm, yy, , kk'
name_list = names.split(',')
result = []
for name in name_list:
if name:
result.append(name)
现在是这样写的:
names = 'jianpx, yy, mm, , kk'
result = [name for name in names.split(',') if name.strip()]
##模拟c语言中的 a?b:c
在python里面可以这样做:
return_value = True if a == 1 else False
从而代替了这样的代码:
if a == 1:
return_value = True
else
return_value = False
##用Decorator抽离公用代码或者解耦
例如要对一个函数做cache,对一个操作限制权限,如果需求随时可能变化,就是说有可能不需要做cache或者不需要做权限的时候,你如果把实现放到这些函数体里面,那么这时你必须把这些代码删除,而且要很小心。但是如果你用Decorator去做的话, 只要删除函数头顶上的@那一行就可以了。Django经常用这种方法做权限控制。
熟悉decorator的应该都很容易理解。
##如何将list的元素倒序并且生成到新的list呢?
看到一个用list的slice做到的 :
a = [1,2,3,4]
c = 'abcdef'
aa= a[::-1]
cc = c[::-1]
如果不用生成新的list,直接调用a.reverse()就得了。但是字符串类型没有reverse的方法.
关于list的slice特性, 其实也许很多人平时只是用list[start:end] 这样的, 这个意思是从start开始,每个元素都放到新的list里面, 直到end。但是其实还可以每隔N个元素才取一次的, 这种情况要3个参数:·list[start:end:step]
,step
就是间隔了。
##a = [i for i in xrange(5)] 和 a = (i for i in xrange(5))
虽然看上去是一样都生成了5个元素,但是
前者是一个list对象, 如果遍历的话 for item in a
就会一下子返回全部元素然后再遍历, 而后者是个Generator,
用for item in a遍历是每次只是返回一个元素, 这样的好处是省内存(在list很大的情况下)。
##python的all函数可以简化逻辑表达式有很多”与“的时候的写法
比如:
a, b, c = True, False, True
if a and b and c:
return True
else:
return False
可以简化成:
return all([a, b, c])
由此可以看到all函数的作用是判断当且仅当参数里面都为真的时候返回真, 否则返回假。
但是这里更深入的话涉及all的判断顺序和传入的参数是list还是iterable对象是不同的。