Python的字典(Dict)是如何存储的

  

  

Python的字典有好多个名称(“映射”、“哈希”,“散列”或者”关系数组”),那你知道为什么字典会被称为哈希(翻译为“哈希”或“散列”)吗?
  

  

你知道为什么字典对于键(键)的存储数据要求比较严格,但对于对应的值(值)的存储却要求很宽松吗?
  

  

读完这篇文章,你将深刻理解这些问题背后的真相!
  

  

  

首先我们来解释一下什么是散列,来自维基百科:
  

  

散列函数(或散列算法,又称哈希函数、英语:哈希函数)是一种从任何一种数据中创建小的数字”指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。该函数将数据打乱混合,重新创建一个叫做散列值的指纹。散列值通常用来代表一个短的随机字母和数字组成的字符串。好的散列函数在输入域中很少出现散列冲突。在散列表和数据处理中,不抑制冲突来区别数据,会使得数据库记录更难找到。
  

  

世界上没有两片完全相同的树叶,也没有两个相同的指纹,散列函数是用于从数据中创建小的数字指纹的方法。
  

  

我们看下图示:

  

 Python的字典(Dict)是如何存储的

  

如图,Python调用内部的散列函数,将键(关键)作为参数进行转换,得到一个唯一的地址(这也就解释了为什么给相同的键赋值会直接覆盖的原因,因为相同的键转换后的地址是一样滴),然后将值(值)存放到该地址中。
  

  

对于Python来说,键(关键)必须是可哈希的,换句话说就是要可以通过散列函数计算出唯一地址的。那如果拿一个变量当键(键)可以吗?肯定不行。因为变量随时都可能改变,不符合可哈希原则。
  

  

同样的,列表,字典,集合这些都是可变的,所以都不能做为键(键)来使用。
  

  

那有朋友可能会问,那元祖呢?元祖总该是不变的吧?
  

  

其实不然,因为元祖里边可以存放列表这类可变因素,所以如果实在想拿元祖当字典的键(关键),那必须对元祖做限制:元组中只包括像数字和字符串这样的不可变元素时,才可以作为字典中有效的键(关键)。
  

  

另外还需要注意的一点是,Python的哈希算法对相同的值计算得到的结果是一样的,也就是说12315和12315.0的值相同,他们被认为是相同的键(关键)。

  

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

Python的字典(Dict)是如何存储的