1、是否有序的问题
注意:这里的有序和无序不是指集合中的排序,而是是否按照元素添加的顺序来存储对象。
1)list(列表)是按照元素的添加顺序来存储对象的,因此是有序的。
2)tupple(元组)与列表类似,不同之处在于元组里的元素不能被修改。
[注]空元组可以用没有包含内容的圆括号来表示;只一个值,必须加 个逗号 (,);元组的元素不能被修改,但可以对元组进 行连接组合。
3)dict(字典),它的存储结构是哈希表<key,value>键值对,其中key必须是唯一的,但value可以重复。
(注意dict对应与Java中Map结构)
这里对dict做更深一层的叙述,前面已经说了,它的存储结构是哈希表。
哈希表(Hash Table,又称为散列表),是一种线性表的存储结构。通过把每个对象的关键字k作为自变量,通过一个哈希函数h(k),将k映射到下标h(k)处,并将该对象存储在这个位置。
例如:数据集合{1,6,7,9},假设存在哈希函数h(x)使得h(1) = 0, h(6) = 2, h(7) = 4, h(9) = 5,那么这个哈希表被存储为[1,None, 6, None, 7, 9]。当我们查找元素6所在的位置时,通过哈希函数h(x)获得该元素所在的下标(h(6) = 2),因此在2位置即可找到该元素。
从这个例子可以看出,因为这个特性,字典读取的效率比较高,数据规模越大明显。所以mongdb这种非关系型数据库在大的数据方面比较流行。
因此他不是按照元素的添加顺序来存储对象的,所以dict(字典)是无序的。
4)对于set(集合)更加复杂,这里先列出它的一些性质。
- 确定性:集合中的元素必须是确定的;
- 互异性:集合中的元素互不相同,例如:集合A={1,a},则a不能等于1);
- 无序性:集合中的元素没有先后之分,例如:集合{3,4,5}和{3,5,4}算作同一个集合。
Python 3.x中的set特征与数学中类似。我们之前学过list、tuple以及dict。其实,set与dict大致相同,但set没有Value,只有key。因此,set只是一组key的集合。由于key不能重复,所以,在set中,没有重复的key。
数据结构 | 有序性 |
---|---|
list(列表) | 有序 |
tupple(元组) | 有序 |
dict(字典) | 无序 |
set(集合) | 无序 |
2 dict与set的实现原理
以下内容来自于:python 下的数据结构与算法---8:哈希一下【dict与set的实现】
2.1Hash的定义
Hash,一般翻译做“散列”,就是把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值。【不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值】
2.2dict与set的实现原理
dict与set实现原理是一样的,都是将实际的值放到list中。唯一不同的在于hash函数操作的对象,对于dict,hash函数操作的是其key,而对于set是直接操作的它的元素,假设操作内容为x,其作为因变量,放入hash函数,通过运算后取list的余数,转化为一个list的下标,此下标位置对于set而言用来放其本身,而对于dict则是创建了两个list,一个list该下表放此key,另一个list中该下标方对应的value。
其中,我们把实现set的方式叫做Hash Set,实现dict的方式叫做Hash Map/Table(注:map指的就是通过key来寻找value的过程)
2.3hash碰撞及其解决方法
哈希冲突:由于哈希表的下标范围是有限的,而元素关键字的值是接近无限的,因此可能会出现h(102) = 56, h(2003) = 56这种情况。此时,两个元素映射到同一个下标处,造成哈希冲突。
解决哈希冲突:
- 拉链法
将所有冲突的元素用链表连接,原理图如下,其实就是将发生有冲突的元素放到同一位置,然后通过“指针“来串联起来
- 开放寻址法
通过哈希冲突函数得到新的地址
在字典键值对数量不多的情况下,几乎不会发生哈希冲突,此时查找一个元素的时间复杂度为O(1)。
hashTable,而实际中的dict就是由hashTable扩展而来的,具体的源码见python 下的数据结构与算法---8:哈希一下【dict与set的实现】。