Day16:高级特性

切片

取一个list或tuple的部分元素,可以这样操作:

 # 从索引0开始取,到3为止,不包括3.
 list[0:3]
 tuple[0:3]

练习

利用切片操作,实现一个trim()函数,去除字符串首尾的空格

 def trim(s):
     if len(s) == 0:
         return s
     while len(s) != 0 and s[0] == ' ':
         s = s[1:]
     while len(s) != 0 and s[-1] == ' ':
         s = s[:-1]
     return s

总结:这其实是一个比较笨的方法,绕过了数组下标越界的判断。当遇到空字符串和空格字符串时,尤其是空字符串,如果判断s[0]==0.

这时程序会报错。

这里选择的解决方法是,每次都先进行长度的判断。

还有另外一种方法更好:

 def trim(s):
    while s[:1] == ' ':
        s = s[1:]
    while s[-1:] == ' ':
        s = s[:-1]
    return s

在判断循环条件时直接只对第一个或最后一个字符判断,在进行这样的判断时,python编译器在遇到切片越界时不会报错。

迭代

如果给定一个listtuple,我们可以通过for循环来遍历这个listtuple,这种遍历我们称为迭代(Iteration)。

在迭代dict时,默认迭代key,也可以用 d.values()选择迭代value,可以选择d.items()迭代 键和值。

 for k in d()
 for v in d.values()
 for k,v in d.items()

字符串也是可迭代对象,

 for ch in 'ABC'
 >>> A
 >>> B
 >>> C

判断一个对象是否为迭代对象。

方法是通过collections.abc模块的Iterable类型判断:

 from collections.abc import Iterable
 print(isinstance('123', Iterable))   >>> TRUE
 print(isinstance([1,2,3], Iterable)) >>> TRUE
 print(isinstance(123, Iterable))       >>> FALSE

如果要对list实现类似Java那样的下标循环怎么办?Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:

 l = ['a', 'b', 'c']
 for i,value in enumerate(l):
    print(i,value)
 # 生成的i值索引从0开始

列表生成式

列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。

要生成list[1,2,3,4,5,6,7,8,9,10]时,可以用

 list(range(1,11))

如果要生成[1x1, 2x2, 3x3, ..., 10x10]怎么做?方法一是循环:

 l = []
 for x in range(1, 11):
    l.append(x * x)

方法2:

 [x*x for x in range(1,11)]

写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来,十分有用,多写几次,很快就可以熟悉这种语法。

for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:

 print([x*x for x in range(1,11) if x % 2 == 0])
 >>> [4, 16, 36, 64, 100]

还可以使用两层循环,可以生成全排列:

 print([m+n for m in 'XYZ' for n in 'ABC'])
 >>> ['XA', 'XB', 'XC', 'YA', 'YB', 'YC', 'ZA', 'ZB', 'ZC']

运用列表生成式,可以写出非常简洁的代码。例如,列出当前目录下的所有文件和目录名,可以通过一行代码实现:

 import  os
 print([d for d in os.listdir('.')])
 >>> ['.idea', '01.hello.py', 'main.py', 'test.py', 'venv']

列表生成式也可以使用两个变量来生成list:

 >>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
 >>> [k + '=' + v for k, v in d.items()]
 ['y=B', 'x=A', 'z=C']

最后把一个list中所有的字符串变成小写:

 >>> L = ['Hello', 'World', 'IBM', 'Apple']
 >>> [s.lower() for s in L]
 ['hello', 'world', 'ibm', 'apple']

在一个列表生成式中,for前面的if ... else是表达式,而for后面的if是过滤条件,不能带else

 >>> [x if x % 2 == 0 else -x for x in range(1, 11)]
 [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]

练习:字符串变小写,其余变量丢弃

 L1=[...]
 L2 = [x.lower() for x in L1 if isinstance(x, str)]

生成器

如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

 >>> L = [x * x for x in range(10)]
 >>> L
 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
 >>> g = (x * x for x in range(10))
 >>> g
 <generator object <genexpr> at 0x1022ef630>

创建Lg的区别仅在于最外层的[]()L是一个list,而g是一个generator。

 

上一篇:shell中文本处理的基本方式


下一篇:【系统分析与设计】软件开发模式之敏捷开发(Scrum)分析