pythonic

pythonic:很python,指Python的惯用和特有写法
备注,在下文中,P,指代pythonic,NP,指代non-pythonic

相比于NP,P的写法简练,明确,优雅,绝大部分时候执行效率高,代码越少也就越不容易出错。好的程序员在写代码时,应该追求代码的正确性,简洁性和可读性,这恰恰就是pythonic的精神所在。

Examples:
a=3
b=1
P: $1 \leq b \leq a < 10 $ \(\quad\)#true
NP: $b\geq 1 $ and $b\leq a $ and a < 10 $\quad $ #true

真假值表(记住了假你就能省很多代码!)

\(\quad\quad\quad\quad\quad\quad\)
True \(\quad\quad\quad\quad\) False
非空字符串 \(\quad\quad\) 空的字符串 ''
非0数字 \(\quad\quad\quad\quad\)数字0
非空容器\(\quad\quad\quad\) 空的容器 [] () {} set()
其他任意非False\(\quad\) None

字符串反转
p:

def reverse_str(s):
    return s[::-1]

NP

def reverse_str(s):
    t=''
    for x in xrange(len(s)-1,-1,-1):
        t+=s[x]
    return  x

字符串列表的连接
P:

strList = ["Python", "is", "good"]  
res =  ' '.join(strList) #Python is good

NP:

res =''
for s in strList:
    res += s+' '

列表推导式

P:
l=[x*x for x in range(10) if x%3==0] #l=[0 9 36 81]

NP:
l=[]
for x in range(10):
    if x % 3==0:
        l.append(x*x)

字典的默认值
P

dic = {'name':'Tim', 'age':23}  
 
dic['workage'] = dic.get('workage',0) + 1
#dic = {'age': 23, 'workage': 1, 'name': 'Tim'}

NP

if 'workage' in dic:
    dic['workage'] += 1
else:
    dic['workage'] == 1

for...else...的else部分用来处理没有从for循环中段的情况。

三元符的代替
a=3
P:

b=2 if a>2 else 1

NP:

if a>2:
    b=2
else 
    b=1

Enumerate
P:

array = [1,2,3,4,5]
for i,e in enumerate(array,0):#
    print(i,e)
#enumerate的第二个参数可以调整索引下标的起始位置,默认为0。

NP:

for i in xrange(len(array)):
    print i ,array[i]

使用zip创建键值对
P:

keys =['Name','Sex','Age']
values=['Tim','Male',23]
dic = dict(zip(keys,values))

NP:

dic={}
for i,e in enumerate(keys):
    dic[e] = values[i]

Python程序在函数内执行得更快
因为局部变量与全局变量的差异,本地变量是存在一个数组中(直到),用一个整型常量去访问,而全局变量存在一个dictionary中,查询很慢。

python 中条件表达式是 lazy evaluation 的,也就是说如果存在条件表达式 if x and y,在 x 为 false 的情况下 y 表达式的值将不再计算。因此可以利用该特性在一定程度上提高程序效率。

在字符串连接的使用尽量使用 join() 而不是 +

使用isinstance而不是type进行类型判断
isinstance(seq, (list, tuple))

(func1 if y == 1 else func2)(arg1, arg2)#func1将被调用如果y等于1的话,反之func2被调用。两种情况下,arg1和arg2两个参数都将附带在相应的函数中。

创建类时,你可以使用__getitem__,让你的类像字典一个工作

class MyClass(object):
     def __init__(self, a, b, c, d):
          self.a, self.b, self.c, self.d = a, b, c, d
     def __getitem__(self, item):
          if item is Ellipsis:
             return [self.a, self.b, self.c, self.d]
         else:
             return getattr(self, item)
x = MyClass(11, 34, 23, 12)
x['a']
x[...]#这行是Ellipsis在发挥作用

在Python里,函数的默认值在函数定义的时候实例化,而不是在调用的时候,

def foo(numbers=[]):
numbers.append(9)
print(numbers)
foo()#[9],对于该函数,不传参数时,numbers此时是默认值,变为对默认值append(9),因为list是可变对象,不可变对象不存在这种现象
def foo(numbers=None):
if numbers is None:
numbers =[]
numbers.append(9)
print numbers

        

该代码会报错,因为Python是一个声明一个声明执行的,而不是一行一行执行的。

bar = 42
def foo():
print(bar)
bar = 0
foo()

因此,请不要用全局变量,如果想保存在代码丽至始至终用到的值的时候,把它定义为一个类的属性。

class Baz(object):
bar = 42#此处不能定义为self.bar,必须要类实例对象才能访问self,因此更改类实例对象不能起到全局变量的作用,要更改类对象才行。

def foo():
print (Baz.bar)
bar =0
Baz.bar =8
print(bar)
print(Baz.bar)



class Baz(object):
def pris(self):
print(1)
Baz.pris(3)#python里一切皆对象,这里类对象调用其方法pris,self==3
Baz().pris()#Baz()是类实例对象,self生效


同时迭代多个seq

nfc = ["Packers", "49ers"]
afc = ["Ravens", "Patriots"]
for teama, teamb in zip(nfc, afc):
print teama + " vs. " + teamb


列表转换字符串

teams = ["Packers", "49ers", "Ravens", "Patriots"]
print ", ".join(teams)

拆箱以及*

a, *b, c = [1, 2, 3, 4, 5]


列表展开

a=[[1,2],[3,4],[5,6]]
sum(a,[])


a = [('2011-03-17', '2.26', 6429600, '0.0'), ('2011-03-16', '2.26', 12036900, '-3.0'),
('2011-03-15', '2.33', 15615500,'-19.1')]
b = sorted(a, key=lambda result: result[1],reverse=True)

posted @ 2018-01-31 16:06  blog_hfg  阅读(163)  评论(0)    收藏  举报