今天学习python的高级特性,觉得切片和生成器是非常有用的工具。
一、切片(slice)
切片操作符能够使程序员很方便的去指定范围的数,比如 L[0:3] 就是指从0开始,到3结束,也就是取到2,当然也是可以通过-1、-2来倒数切片。切片操作可以list、tuple,也可以针对字符串。
这里主要通过一个例子来帮助理解:利用切片实现一个函数,去掉字符串的首尾空格。
def trim(s):
if s[:1] != ' ' and s[-1:] != ' ':
return s
if s[0] == ' ':
return (trim(s[1:]))
if s[-1] == ' ':
return (trim(s[:-1]))
这里通过递归来实现。实际上通过切片能够将长度为0的字符串的判断涵盖进去,不需要再去判断
len(s)。
二、生成器(generator)
生成器也是非常有用的一种机制。它的特点简单来说就是一边循环一边计算,再循环中不断推算出下一个元素。
我们可以只通过将列表生成式的 [ ] 改成(),就可以变成生成器,如下:
M = (x*x for x in range(6))
for i in M:
print(i)
注意生成器它是一个算法,不能简单的用 print(M)来输出所有元素。
而且一个函数也可以作为一个generator,函数中包含了 yield 关键字,那么它就是一个generator,它的执行流程是每次遇到yield 返回,再次执行时从上次的 yield 语句处继续执行。
这里我通过一个例子来帮助理解:
杨辉三角定义如下:
1
/ \
1 1
/ \ / \
1 2 1
/ \ / \ / \
1 3 3 1
/ \ / \ / \ / \
1 4 6 4 1
/ \ / \ / \ / \ / \
1 5 10 10 5 1
把每一行看做一个list,试写一个generator,不断输出下一行的list:
代码如下:
def triangles():
s = [1]
while True:
yield s[0:len(s)]
s.append(0)
s = [s[i - 1] + s[i] for i in range(len(s))]
这里需要注意的是 yield 语句,我 yield 的是 s[0:len(s)],而不是 s,其实当前的 s 和 s[0:len(s)] 是相等的,但是返回s会出现问题,我的理解是返回 s 后,实际上是浅拷贝,再次执行时的append会在上次返回结果上append,就会造成测试的错误,而 s[0:len(s)] 是重新开辟了空间,虽然和 s 是相等的,但是互相不影响。