概念
抽象基类:ABC, Abstract Base Class,ABC还有一个概念,是一个编程语言
序列
内置序列类型
分类
可分为容器类型和扁平类型
容器类型有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可以一步到位,该方法还可节省一点时间
列表以外的数据类型
大量数据时可用array类型,和list相比优点是存储的对象不是对象,而是C语言字节表述,类似C语言的数组,存储有优化(好像没多少),而且array是扁平类型。数据量大且相同类型但希望像list操作,可以用内置类型array,也可用np的array(待验证)等类型
频繁增删元素时,deque更快点
频繁查找元素可用set,set类型对元素查找有优化
数组
array可二进制读写文件,读写速度快,比常规读写文件快5倍以上,且空间相比于文本文件小
pickle也可快速序列化,速度和array差不多,但支持序列化数据类型,array比pickle可能多,array几乎支持全部内置类型,自定义类没复杂实现也可支持
内存视图
memoryview是内置类。功能是不复制对象内存情况下支持切片等操作
memoryview.cast方法可将原对象打包成其他类型返回,是新对象,但新对象没有新分配内存,而是和原对象用一个内存,所以改新对象后原对象也会变,反之亦然
numpy和scipy
scipy基于numpy,专为线性代数,积分,统计学等方面计算设计。
时间打印,time.perf_counter更准确,验证一下
双端队列和其他队列
对列表来说,如果元素很多,删第一个元素会很耗时,此时可使用队列collections.deque(线程安全),deque也可限制队列长度,超过长度时会删除过期元素
还有几个内置库提供队列类
queue 线程安全
multiprocessing 进程间通信使用
heapq 堆