简洁的python

条件表达式

一般情况下,条件分支只有简单的返回或对同一变量进行赋值操作时,可以转为条件表达式.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#1.改写条件语句
if x > 0:
y = math.log(x)
else:
y = float('nan')
#简洁写法
y = math.log(x) if x > 0 else float('nan')


#2.改写递归函数
def fac(x):
if x == 0:
return 1
else:
return x * fac(x-1)
#简洁写法
def fac(x):
return 1 if x == 0 else x * fac(x-1)

列表解析(list comprehension)

将一个列表转为另一个时用更少的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#1.映射操作
def capitalize_all(t):
res = []
for s in t:
res.append(s.capitalize())
return res
#简洁写法
def capitalize_all(t):
return [s.capitalize() for s in t]

#2.过滤操作
def only_upper(t):
res = []
for s in t:
if s.isupper():
res.append(s)
return res
#简洁写法
def only_upper(t):
return [s for s in t if s.isupper()]

生成器表达式

类似于列表解析但又不同,经常和sum,max,min之类的函数配合使用

1
2
3
4
5
6
7
8
9
>>> l=[x**2 for x in range(5)]
>>> l
[0, 1, 4, 9, 16]

>>> g = (x**2 for x in range(5))
>>> g
<generator object <genexpr> at 0x7f33f66f2780>
>>> sum(g)
30

any和all

any接收一个布尔值组成的序列,其中任何值是True时返回True.

all接收一个布尔值组成的序列,所有值是True时返回True.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#发现禁止字母,返回False
def avoids(word,forbidden):
for letter in word:
if letter in forbidden:
return False
return True
#改写
def avoids(word,forbidden):
return not any(letter in forbidden for letter in word)

#单词必须使用required中的全部字母
def uses_all(word,required):
for letter in required:
if letter not in word:
return False
return True
#改写
def uses_all(word,required):
return all(letter in word for letter in required)

集合

有些问题可以借助集合处理.

1
2
3
4
5
6
7
8
9
10
11
12
#第一次出现时加入词典,再次出现时函数返回True
def has_duplicates(t):
d={}
for x in t:
if x in d:
return True
d[x] = True
return False

#同一函数借助集合的简写形式
def has_duplicates(t):
return len(set(t))<len(t)

计数器

将每个键映射到其出现次数,键是可散列的.

类似于集合,提供了一些加法,减法,交集,并集的操作.还有一个常用的most_common方法,返回一个值-频率对的列表,按照最常见到最少见排序.

1
2
3
4
5
6
7
8
9
10
11
>>> from collections import Counter
>>> count=Counter('parrot')
>>> count
Counter({'r': 2, 'a': 1, 'p': 1, 't': 1, 'o': 1})

>>> for val,freq in count.most_common(3):
... print(val,freq)
...
('r', 2)
('a', 1)
('p', 1)

命名元组

提供了快速定义简单类的方法;如果类变得很复杂,可以定义新类继承当前的命名元组,或者使用原始类定义.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#定义一个Point对象
class Point:
def __init__(self,x=0,y=0):
self.x = x
self.y = y

def __str__(self,):
return '(%g,%g)'%(self.x,self.y)

#改写
from collections import namedtuple
Point = namedtuple('Point',['x','y'])


>>> Point
<class '__main__.Point'>
>>> p = Point(1,2)
>>> p
Point(x=1,y=2)

收集参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#收集任意个数的按位实参并输出
def printall(*args):
print(args)

>>> printall(1,2.0,'3')
(1, 2.0, '3')
>>> printall(1,2.0,third='3')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: printall() got an unexpected keyword argument 'third'

#收集关键词实参
def printall(*args,**kwargs):
print(args,kwargs)

>>> printall(1,2.0,third='3')
((1, 2.0), {'third': '3'})

处理参数很多的函数时,创建和传递字典来指定常用的选项是非常有用的.