概念
抽象基类:ABC, Abstract Base Class
序列
内置序列类型
分类
可分为容器类型和扁平类型
容器类型有list, tuple, collections.deque等,存储元素类型可不同,存储的元素也是内容的引用而非内容实际占用内存
扁平类型有str, bytes, array.array, bytearray, memoryview等,
按结构是否可变也可分为可变类型和不可变类型
可变序列有list, bytearray, array.array, collections.deque, memoryview
不可变序列有tuple, str, bytes
可变类型与不可变类型元类
可变序列继承了不可变序列并为可变实现了方法
列表推导和生成器表达式
列表推导
列表推导即为将for循环用一行代码代替,起到简化作用,比如x = [i for i in range(5)]。但如果列表推导过长也可以写为for循环,怎么选取决于自己
列表推导在python2存在变量泄漏,但在python3不存在。因为py3里列表推导里元素空间为局部变量,不会影响到外部的同名变量值
列表推导的功能,用filter和map内置函数也可实现,只是可读性不同
生成器表达式
吧方括号换成圆括号,好处是节省内存,不会直接生成结果,而是用的时候才生成,只生成一次,第二次就没了
元组
元组拆包
不光可以在赋值时拆包,也可在print等场景使用:a = (1, 2, 3); print('%s/ %s, %s' % a)
*可以拆包或赋值,赋值的结果类型是list。*后跟的变量可在任意位置
具名元组
即collections.namedtuple
构造函数参数可以是可迭代对象
对具名元组类的._fields方法可看有哪些定义的属性
具名元组类可用._make方法入参,创一个实例
具名元组实例的._asdict可转为collections.OrderedDict
切片
对象进行切片访问时,实际会调用对象的__getitem__方法:obj[a: b: c] == obj.__getitem__(slice(a, b, c))
多维切片
py内置类型切片都是一维的,numpy.ndarray实现了多维的支持,形如obj[a:b, c:d]即可实现多维切片访问。
若希望实现多维切片,也需实现__getitem__和__setitem__方法
多维切片可用...实现对剩余维度访问。比如obj[1d, 2d, ...]。...实际是Ellipsis对象的别名,Ellipsis对象是ellipsis类的单一实例(命名大小写反了,就是这么写的,比如bool True False)
序列使用+和*
序列可使用+和*创建全新序列
需注意如果用+和*对已有序列操作,如果是可变序列可能会有副作用,不推荐
序列增量赋值
+=实际调用__iadd__方法,如果没实现__iadd__方法,解释器会调__add__方法
可变序列会实现这个方法,不可变序列没有这个方法
增量赋值不是一个原始操作,因为即使发生异常,操作也可能完成执行,比如+=
可用python tutor辅助查看python内存分配
list.sort和sorted内置函数
list.sort不返回,原地排序;sorted不原地排序,而是返回一个排序好的序列
bisect
可用来二分法查找已排序序列元素
bisect.bisect为bisect.bisect_right,还有一个函数bisect.bisect_left。调用方法:bisect.bisect(target_queue, target_value),方法会返回要插入的值在有序序列里插入的下标,right和left即规定插入目标元素的左边还是右边
bisect插入元素:用bisect.insort方法。调用:bisect.insort(queue, target_value)。插入后方法会保持序列升序。
相比于bisect.bisect,bisect.insort可以一步到位,该方法还可节省一点时间