pythonic examples

    写python应该有一年了, 感觉非常好。python果然很优雅。为了防止以后自己忘记了,特意摘录下一些pythonic examples,意思是这些例子是属于python转用的写法。会让你觉得用python用的很爽~这也是脚本语言的强大之处。

如无特别说明, 所有这里的代码都只是运行在python2.5下面的。

 

 

1. 百分号的使用:

通常我们都是这样格式化字符串的:

 

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

 

 

2. 用两个元素之间有对应关系的list构造一个dict:

运用zip可以非常简单的实现:

 

names = ['jianpx', 'yue']
ages = [23, 40]
m = dict(zip(names,ages))

 

 zip的使用可以help(zip)或者查看官方文档。

 

3.  交换两个值:

在其他语言可能要一个临时变量和三句话:

temp = a

a = b

b = tem

但是在python,一句就ok了,而且不需要临时变量:

a,b = b,a

右边的b,a 其实可以理解成一个tuple。

 

4. 数量多的字符串相连用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)


 

5. 判断一个key是否在一个dict里面:

以前很经常犯的一个mistake是这样做:

 

if key in dict_example:
    do something

 现在要这样写,就不用使用in操作了。

 

if dict_example.has_key(key):
    do something
 

6. 去掉list中的重复元素:

 

old_list = [1,1,1,3,4]
new_list = list(set(old_list))

 

7. 如果对两个都没有重复元素的列表对象,要判断某个元素是否在列表里面的话,当这个列表很大的时候,用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)

 

 

8. 读文件操作:

以前是这样写的:

 

#默认文件存在,不处理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的可以参考我的这篇文章:http://jianpx.iteye.com/blog/505469

 

 

9.  输出数组的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)

 

10.  关于使用map、filter、reduce的例子网上很多,这里不细说了,它们的使用也是pythonic的examples

 

11. 分隔一个字符串,去里面的元素,但是空白字符串不要:

例如, 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()]

 

12. 模拟c语言中的  a?b:c

在python里面可以这样做:

 

return_value = True if a == 1 else False

 从而代替了这样的代码:

 

if a == 1:
    return_value = True
else 
    return_value = False

 

13 用Decorator抽离公用代码或者解耦

例如要对一个函数做cache,对一个操作限制权限,如果需求随时可能变化,就是说有可能不需要做cache或者不需要做权限的时候,你如果把实现放到这些函数体里面,那么这时你必须把这些代码删除,而且要很小心。但是如果你用Decorator去做的话, 只要删除函数头顶上的@那一行就可以了。Django经常用这种方法做权限控制。

熟悉decorator的应该都很容易理解。

 

 

 

现在就总结了这些,如果大家有其他的pythonic examples,欢迎留言更新或者拍砖!

最后上一段python的禅:


Python 2.5.2 (r252:60911, Jan 24 2010, 14:53:14) [GCC 4.3.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!

 

 

 

=====2011年的分割线======================

 

14. 如何将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就是间隔了。

 

 

 

15.   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很大的情况下)。

 

 

16. 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对象是不同的。迟些再写了。

 

你可能感兴趣的:(apple,python,django,F#,idea)