python编码之pythonic

 Python是一门很优雅的语言,有一些不同于C/C++的专有用法,使得python的编码变得简洁明了。

先看看python中的八荣八耻:

以动手实践为荣 , 以只看不练为耻 ; 
以打印日志为荣 , 以单步跟踪为耻 ; 
以空格缩进为荣 , 以制表缩进为耻 ; 
以单元测试为荣 , 以人工测试为耻 ; 
以模块复用为荣 , 以复制粘贴为耻 ; 
以多态应用为荣 , 以分支判断为耻 ; 
以Pythonic为荣 , 以冗余拖沓为耻 ; 
以总结分享为荣 , 以跪求其解为耻 ; 

一道小题目:

    把0-9中的偶数挑出来并放到一个数组中

 

一.%号的使用:

Python字符串的格式化通常使用%

    print 'hello world programme by %s' % 'python'

如果程序有多个%,那就得取决于%后的变量取名是否清晰可靠,这种时候有一种dict来格式化的%,可读性非常强:

#字符串

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))

 

三.交换两个值:

在其他语言中可能需要一个临时变量:

tmp = a

a =b

b = tmp

python中只需要 a,b = b,a

 

四.数量多的字符串相连用join

python字符串效率问题之一就是在连接字符串的时候使用‘+’号,例如 s = 's1' + 's2' + 's3' + ...+'sN',总共将N个字符串连接起来,但是使用+号的话,python需要申请N-1次内存空间,然后进行字符串拷贝。原因是字符串对象PyStringObjectpython当中是不可变对象,所以每当需要合并两个字符串的时候,就要重新申请一个新的内存空间(大小为两个字符串长度之和)来给这个合并之后的新字符串,然后进行拷贝。所以用+号效率非常低。建议在连接字符串的时候使用字符串本身的方法joinlist),这个方法能提高效率,原因是它只是申请了一次内存空间,因为它可以遍历list中的元素计算出总共需要申请的内存空间的大小,一次申请完

#以前是这样写的

fruits = ['apple', 'banana']

result = ''

for f in fruits:

    result += f

 

#现在可以这样:

fruits = ['apple', 'banana']

result = ''.join(fruits)

 

五.判断一个key是否在一个dict里面,使用has_key而不使用in

    if dict_example.has_key(key):

    do something

 

六.去掉list中的重复元素:(上周已经有说过)

使用set

old_list = [1,1,1,3,4]

new_list = list(set(old_list))

 

七.读文件操作:

原有的方式:

#默认文件存在,不处理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

 

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

 

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

例如: 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()](推荐使用)

ps:利用这样的形式写一个把0-9中的偶数挑出来并放到一个数组中:

[i for i in range(10) if i % 2 ==0]

[I for I in range(0,10,2)]

 

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

return_value = True if a == 1 else False

替代比较繁杂的写法:

if a == 1:

    return_value = True

else 

    return_value = False

 

十一.@符号的使用,可以做函数的预处理,权限控制,Web 权限校验 ,Cache等等(推荐研究使用)

 

十二. all函数的使用

主要用于简化与的逻辑表达式:

a, b, c = True, False, True

if a and b and c:

return True

else:

return False

可以简化成:

Return all([a,b,c])

all函数的作用是判断当且仅当参数里面都为真的时候返回真, 否则返回假

 

十三让函数返回多个值:

这个问题涉及到如何直接传递或改变引用,在C或者其他编程语言中的方法是给这个函数传入引用或指针:

Void foo(int*a, float*b){

*a =3;

*b =5.5;

}

int alpha;

int beta;

foo(&alpha,&beta);

python可以通过给函数传递序列参数来返回结果,但写出来的代码十分难看,可以使用这样的方式:

def foo():

return 3, 5.5

alpha, beta = foo()

 

十四.合并两个文件:

file_one = open ('1.txt') 
file_two = open ('2.txt') 
file_new = open ('new.txt','w+') 
line4one={} 
line4two={} 
line4new={} 
i = 0 
linenums_one = len(file_one.readlines())#行数 
linenums_two = len(file_two.readlines()) 
file_one.seek(0,0) 
file_two.seek(0,0) 
linenums = linenums_one if linenums_one < linenums_two else linenums_two #比较出行数较小的值 
while i < linenums: 
print str(i) 
line4one = file_one.readline(); 
line4two = file_two.readline(); 
line4new = str(line4one).replace('n','t') + line4two #将第一个文件的换行符换成tab,然后和第二个文件的对应行叠加 
file_new.write(str(line4new)); 
i = i+1 
print 'finished' 
file_one.close() 
file_two.close() 
file_new.close()

 

简化后的版本:

file_one = open ('1.txt') 
file_two = open ('2.txt') 
file_new = open ('new.txt','w+') 
while 1: 
line1 = file_one.readline() 
line2 = file_two.readline() 
if line1 and line2: 
file_new.write(line1.rstrip() + 't' + line2) 
else: 
break 
print 'finished' 
file_one.close() 
file_two.close() 
file_new.close()

 

再次简化:

data1 = file('1.txt').readlines() 
data2 = file('2.txt').readlines() 
linenums = min(len(data1),len(data2)) 
result = [ 't'.join((data1[i],data2[i])) for i in range(linenums)]

file_new = open ('new.txt','w+') 
file_new.writelines(result)

 

最后简化:

for l1,l2 in zip(open('file1.txt').readlines(),open('file2.txt').readlines()):

  ……….

 

 

十五.几个pythonic的内建函数,函数式编程:

简单函数: 

def lowercase(x):

    return x.lower()

其实可以这样:lowercase = lambda x: x.lower()

filter函数,可以按照条件来过滤数组 

>>> a = [1, 2, 3, 4, 5]

>>> filter(lambda x : x % 2==0, a)

[2, 4]

map函数,可以对数组每个元素进行操作,当然如果你想for一次,也不反对 

>>> a = [1, 2, 3, 4, 5]

>>> map(lambda x : x+2, a)

[3, 4, 5, 6, 7]

reduce函数,对一个数组进行求和 

>>> reduce(lambda x, y : x+y, a)

15

 

 

十六列表推导:

重新实现前面的mapreducefilter

map,数组里每个值都乘以2

>>> [i * 2 for i in range(1, 10)]

[2, 4, 6, 8, 10, 12, 14, 16, 18]

reduce,求和 

>>> sum(i for i in range(1, 10))

45

filter,过滤数字 

>>> [i for i in range(1, 10) if i % 2 == 0]

[2, 4, 6, 8]

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值