短路
「短路」可以用下面几句话来解释一下,即先处理简单情况,再处理复杂情况;先处理已知情况,再处理未知情况;先处理耗时短的操作,再处理耗时长的操作。总之,就是让程序尽可能少做无用功,先挑逻辑简单、耗时短部分执行。
- 短路在函数中的使用
在函数内部使用短路,优先处理逻辑简单的部分,可以尽可能的减少程序的缩进,简化代码量,同时使得代码逻辑更加清晰。
# 没有使用短路 def work(cond): if cond: do_work() # 使用了短路 def work(cond): if not cond: # 不符合条件,直接中断函数的执行 return # 这里cond一定符合work的条件 do_work()
- 短路在逻辑运算符中的使用
短路最早就是被使用在逻辑运算中,通过and
和or
运算的特点,可以天然实现短路的特点。
a = 1 and 2 and 3 # a = 3 b = 1 or 2 or 3 # b = 1
缩进灾难
在编写多判断条件或者是多层嵌套循环的程序时,往往会陷入缩进灾难,解决的办法有很多。
多判断条件
多判断条件的代码往往像下面这样,一层嵌套一层。
if a: if b: if c: if d: do_work()
- 使用短路处理多判断程序
# 方法1 if not a: return if not b: return if not c: return if not d: return do_work() # 方法2 cond = [a,b,c,d] # 使用all函数,来保证判断条件全部满足时才为True if not all(cond): return do_work() # 方法3 # 这里等价于手动实现了all函数 if not (a and b and c and d): return do_work()
多层嵌套
for i in range(10): for j in range(10): print(i * j)
使用推导式来解决多层嵌套
loop1 = [i*j for j in range(10) for i in range(10)]
生成器
python中生成器在读取大型文件、需要进行大量计算的时候是很有用的。
# bad with open('test.txt', 'r') as fp: for line in fp.readlines(): ... # good with open('test.txt', 'r') as fp: for line in fp: ...
文件对象本身是一个生成器,可以直接进行迭代,如果直接调用fp.readlines()
相当于将文件内容全部读入内存中,当文件较大时,对内存要求较高。
在计算时,如果需要计算的数据量非常大,可以先不一次性放到列表中,可以通过生成器yield
返回数据。
# bad numbers = [i for i in range(10000000000000)] for n in numbers: print(n * n) # good def numbers(count): for i in range(count): yield i for n in numbers(): print(n * n)
可变参数
- 强制使用关键字进行传递参数
通过*
可以使得后面的a``b``c
参数必须使用关键字传递方法才能传递到函数内部
def work(key, * a, b ,c): ...
- 使用可变位置参数
下面是使用可变位置参数创建一个size大小的数据的函数,size可能是1维,也可能是2维,也可能是任意维度。
def work(*size, padding=0): if len(size) == 0: return None size = list(size) arr = [padding] * size.pop() while len(size): arr = [arr] * size.pop() return arr
- 使用可变关键字参数,减少参数数量
使用work
是对_work
函数的封装,_work
函数本身有很多参数,在包装以后,可以使用**kwargs
避免将_work
的参数重新写一遍
def work(**kwargs): _work(**kwargs) def _work(a, b, c, d): ...