简介: 可变数据类型和不可变数据类型, 列表,元祖,字符串,集合
1. 可变数据类型和不可变数据类型有哪些
- 可变数据类型
- List(列表), set(集合), dict(字典)
- 不可变数据类型
- number(数字), str(字符串), tuple(元祖), frozenset(不可变集合)
2. 列表和元祖之间的区别
2.1. 主要区别:
列表可变, 数据可以动态变化,
元祖不可变, 大小固定数据量大的时候进行操作,
元祖明显优于列表
2.2. 元祖用于存储**异构(heterogeneous)数据**, 也就是具有不同意义的数据.
列表一般用于存储**同构(homogenous)数据**, 同构数据就是具有相同意义的数据
2.3. 元祖具有结构, 列表具有顺序
3.字典的底层(详细)
1. 字典是Python中最通用的数据结构之一, 可以通过键值对{key: value}来添加和获取数据
2. CPython使用伪随机探测(pseudo-random probing)的散列表(hashtable)作为字典的底层数据结构, 由于这个实现细节, 只有可哈希的对象才能作为字典的键 PS: 可变和不可变数据类型请参考上面
3. PY中所有不可变的内置类型都是可哈希的, 可变类型(列表, 字典, 集合)是不可哈希的, 因此不能作为字典的键
4. 字典的三个基本操作(添加, 获取, 删除)的平均事件复杂度为O(1), 但是他们的平摊最坏情况复杂度为O(N)
- 开放寻址法: 在Python3.6版本之前,字典是无序的, 使用开放寻址法实现hash(散列表), 所有元素都存放在散列表里, 当产生哈希冲突时, 通过一个探测函数计算出下一个候选位置, 如果下一个候选位置还是有冲突, 就通过探测函数继续往下找, 直到找到一个空槽来存放待插入的元素
- hash数组: 只用输出一种数据结构存储, 继承了数组的优点, 对CPU缓冲友好, 易于序列化. 但是对于内存的利用率并不如拉链法, 且冲突代价更高, 当数据量比较小, 装载因子(扩容因子)小的时候, 适合采用开放寻址法
- 拉链法: 将所有关键字为同义词的记录存储在一个单链表中(称为同义词子表), 在哈希表中只存储同义词子表的头指针, 不存在hash冲突, 因为遇到冲突直接追加至当前位置链表尾部即可, 但是极端情况下, 可能冲突都进入同一链表, 会导致当前遍历查找元素时间较长, 解决方案: 当链表过长时, 会升级为红黑树加快查询速度
4.什么是hash碰撞(冲突)
对进行hash运算之后得到的位置进行存储, 但已被占用
5.什么是扩容因子
当hash数组及将达到总大小的2/3时, 会进行扩容, 复制到另外一个块更大的内存中, 常见的扩容因子为0.75