1.Python数组和列表的区别
1.创建方式不同
列表可以直接创建,数组需要引用numpy包
2.存储对象不同
列表可以存储任何的对象,包括数字,字符串,数组,字典等等
数组只能存储单一的数据类型
3.运算方式不同
数组可以进行四则运算,列表只能使用加号进行拼接,拼接之后形成一个新的列表
4.运算效率不同
array数组是为了精确便捷的处理庞大的类似的数据而产生的,他的存储效率要比列表快着很多
2.Python内存管理机制
Python的内存管理机制共分为三部分:1、引用计数 2、垃圾回收 3、内存池机制
一、引用计数
每个对象都会包含一个头部信息,这个头部信息包括:类型标识符和引用计数器!
查看对象的引用计数可以调用sys.getrefcount():
引用计数增加的方式:
1、对象的创建
2、引用的赋值
3、作为容器对象的一个元素
4、作为参数传递给函数
引用计数减少的方式:
1、显示得销毁对象引用
2、该对象的引用被赋值了其它对象
3、从容器对象中移除
4、引用离开作用域,比如函数foo()结束返回
二、垃圾回收
原理:当python对象的引用计数为0时,python解释器会对这个对象进行垃圾回收。
注:在垃圾回收的时候,python不能进行其它任务,所以如果频繁的进行垃圾回收将大大降低python的工作效率,因此,python只会在特定的条件下自动进行垃圾回收,这个条件就是阈值,在python运行过程中,会记录对象的分配和释放次数,当这两个次数的差值高于阈值的时候,python才会进行垃圾回收。
查看阈值:
函数:gc.get_threshold():
为了处理如list、dict、tuple等容器对象的循环引用问题,python引用了标记-清除和分代回收的策略。
标记清除:
标记清除是一种基于追踪回收(tracing GC)技术实现的回收算法,它分为两个阶段:第一阶段是把所有活动对象打上标记,第二阶段是把没有标记的非活动对象进行回收,对象是否活动的判断方法是:从根对象触发,沿着"有向边"遍历所有对象,可达的对象就会被标记为活动对象,不可达的对象就是后面需要清除的对象
分代回收:
分代回收是一种以空间换时间的操作方式,python把所有对象的存货时间分为3代(0、1、2),对应着3个链表,新创建的对象会被移到第0代,当第0代的链表总数达到上限时,就会触发python的垃圾回收机制,把所有可以回收的对象回收,而不会回收的对象就会被移到1代,以此类推,第2代的对象是存活最久的对象,当然分代回收是建立在标记清除技术的基础上的。
三、内存池机制
为了避免频繁的申请和释放内存,python的内置数据类型,数值、字符串,查看python源码可以看到数值缓存范围为 -5 ~ 257,对于 -5 ~ 257 范围内的数值,创建之后python会把其加入到缓存池中,当再次使用时,则直接从缓存池中返回,而不需要重新申请内存,如果超出了这个范围的数值,则每次都需要申请内存。
字符串的 intern 机制:
Python 解释器中使用了 intern (字符串驻留)的技术来提高字符串效率,所谓 intern 机制,指的是:字符串对象仅仅会保存一份,放在一个共用的字符串储蓄池中,并且是不可更改的,这也决定了字符串时不可变对象。
并非全部的字符串都会采用 intern 机制,只有包括下划线、数字、字母的字符串才会被 intern,同时字符数不能超过20个,因为如果超过20个字符的话,Python 解释器就会认为这个字符串不常用,不用放入字符串池子中。
3.python中__new__和__init__的区别
1.__new__是在实例创建之前被调用的,用于创建实例,然后返回该实例对象,是个静态方法。
2.__init__是当实例对象创建完成后被调用的,用于初始化一个类实例,是个实例方法
3.__new__至少要有一个参数cls,且必须要有返回值,返回的是实例化出来的实例,有两种return方式:
return super(父类,cls).__new__(cls)
或者
return object.__new__(cls)
4.__init__有一个参数self,就是这个__new__返回的实例,__init__在__new__基础上完成一些其他初始化的动作,__init__不需要有返回值
4.Python 中的 list、tuple、dict的底层实现的理解
List 本质是顺序表,只不过每次表的扩容都是指数级,所以动态增删数据时,表并不会频繁改变物理结构,同时受益于顺序表遍历的高效性(通过角标配合表头物理地址,计算目标元素的位置),使得python的list综合性能比较优秀;
tuple本质上就是顺序表,不可修改不可扩容,只读;
dict本质上是顺序表,不过每个元素存储位置的角标,不是由插入顺序决定的,而是由key经过hash算法和其他机制,动态生成的,即key通过hash散列,生成value应该存储的位置,然后再去存储这个value;所以dict的查询时间复杂度是o(1);因此,dict的key只能为可hash的对象,即不可变类型;
5.python常用的8种经典数据结构
- python原生数据结构:元组Tuple(),列表List[],集合Set{},字典Dictionary{A:B};
- NumPy包中的数据结构:数组Ndarray(带多种操作),矩阵Matrix(多种线性代数计算);
- Pandas包中的数据结构:序列Series(索引+1列数据),数据框DataFrame(索引+多列数据表)。
NumPy包中的数据结构:数组(Ndarray)矩阵(Matrix)
数组(Ndarray)
创建Ndarray
引入NumPy包,将其命名为np。在引入NumPy包后方可使用数组数据结构
创建数组对象,在NumPy包中:
1.array() 方法可以把序列型对象转换成数组;
2.arange() 方法可以生成自定义终点的一堆数组;
3.ones 生成值全为1的数组;
4.empty() 方法会生成一个给定类型和维度且不进行数据初始化的数组;
5.random() 生成随机数组;
6.linspace() 生成指定起止数值和步长的一维数组,例如生成一个从1到10的元素个数为5的数组
数组可以通过 array[a:b] 从数组中提取子集,也可以在此基础上进行批量赋值操作。
append() 函数可以增加元素或者列表类型的数据,但必须注意维度需要保持一致
使用 delete(x,i,axis=) 方法可以删除数组对象中行或者列,第三个参数 axis 决定了删除的是行还是列,需要删除的对象可以是一个数,也可以是一个元组 axis=0删除行,axis=1删除列
矩阵(Matrix)
创建Matrix
使用mat()方法可以把其他数据结构的对象转换为矩阵类型。
在矩阵中有一下常用属性用于观察矩阵
M.shape 矩阵每维的大小
M.size 矩阵所有数据的个数
M.dtype 矩阵每个数据的类型
矩阵合并。c_() 方法进行连接,根据参数顺序也将决定生产矩阵的结果;r_() 方法用于列连接。
Matrix删除操作
delete() 方法可以删除矩阵的指定行列,具体类似数组中的用法。
矩阵运算,在矩阵运算中,* 被重写用于矩阵乘法,dot() 则用于计算矩阵点乘,如果需要对应位置相乘,则需使用其它函数。
矩阵常用函数。矩阵也可以使用 .T 进行转置。linalg.inv() 可以用于求逆运算,若不存在逆矩阵则报错。
python原生数据结构
元组(Tuple)
使用()、tuple()创建元组,元组可以为空且元素类型可以不同;
若元组中仅包含一个数字,则应该添加逗号以区别运算符号:tup=(1,);
元组一旦创建就无法对其元素进行增加、删除、修改。
元组可以使用下标索引来访问元组中的值。
使用del方法可以删除指定的元组对象,但无法删除指定下标的元组元素。
虽然元组中的元素不允许修改,但可以对元组进行连接组合创建出一个新的元组。
1.len() 返回元组元素个数;
2.max()/min() 返回元组元素中的最大、最小元素。
列表(List)
创建列表
一维列表的创建。使用[]可以创建一个列表对象,列表是一种有序的集合,可以随时添加和删除其中的元素;
多维列表的创建。尽管list默认是一维的,但可以使用[]嵌套创建多维列表。
list[a:b] 返回列表中第a个至第b-1个元素的列表对象;
list[::a] 返回一个从列表第一个元素开始,步长为a的列表对象;
list[i] 返回列表中下标为i的元素,若i为负数,则从列表尾部从后至前访问第i个元素。
append() 可以在列表末尾增加新的项目,可以增加一个元素,也可以增加一个list对象成为多维列表。
List删除操作
remove() 函数可以删除指定值的元素,list.remove(i)会删除list对象中值为i的元素,若不存在则报错;
pop() 函数可以删除指定下标的元素,默认为列表对象的最后一个元素,list.pop(i)将删除下标为i的元素。
list[i]=x 可以直接替换列表中指定下标的元素
reverse() 函数可以使列表倒置;
len() 函数可以返回列表的元素个数;
sort() 函数可以使列表元素升序排列。
列表可以便利的转换为各种数据类型;注意,单个列表无法转换为字典。
集合(Set)
创建Set
集合不会出现重复值,所有元素按照一定的顺序排列,若元素为数字则按数字大小排列,使用set()函数创建集合会自动的拆分多个字母组成的字符串
使用in可以判断a是否在集合中,存在为真,反之为假。
add() 函数可以在集合对象中加入新元素,若元素已存在,则无效果;
使用update表示添加(并非修改)是一个一个添加,并且按照顺序添加进集合。
1.remove() 函数可以将集合中的元素删除,元素不存在会报错;
2.discard() 函数可以删除集合中指定的元素,且元素不存在不报错;
3.pop() 函数可以随机删除集合中的一个元素(在交互模式下删除最后一个元素);
4.clear() 函数可以清空集合
1.len() 函数可以查询集合的长度;
2.copy() 可以复制集合中的元素并生成一个新的集合
3.集合的运算。首先建立两个集合用于运算,在集合运算中,‘-’表示求差,‘&’表示求和,‘|’表示求并集,'^'表示两个集合的并集减去交集
字典(Dictionary)
创建Dict
生成一个字典和一个包含三个字典对象的字典列表。(列表中嵌套字典,students实际上是一个列表,students中的元素是字典)
使用zip方法创建字典。zip() 方法可以返回元组组成的列表,可以用于快速构建字典。
查找第一个学生的学号(显示出第一个字典元素id键的值);此外还可以使用get(key,default=None)方法获取指定键的值。
添加一名学生的信息(增加行,其实是增加列表中一个元素),之后再添加一个学生信息科目(增加列,其实就是增加字典中一个键值对)
使用del删除一名学生的信息(删除行,其实就是删除列表中的一个元素)。再使用pop删除第一个学生的学号(删除某一行中的列,其实是删除字典中的一个键值对)
添加(更改)第一个学生的学号(在列表的第一个字典元素中增加/更改键值对)
字典的键和值可以被单独各自转换为list