Python字典的底层原理

一,字典的底层数据结构

Python字典主要功能是存储键值对形式的数据,底层实现为哈希表,
同样实现的编程语言还有Java,JavaScript等。
python字典通过唯一key值找到value的时间复杂度为O(1),这得益于哈希表的特性。

二,哈希表(散列表)

哈希函数

首先介绍哈希函数,他可以将任意长度的数据映射为128位的编码,
是实现各种索引加速的强有力手段,
常见哈希函数包括MD5,SHA-1,SHA-256等,主要应用场景有安全加密,唯一标识,数据校验,
散列函数也就是接下来要介绍的哈希表的实现。

哈希表

用顺序表存储键值对,通过哈希函数计算出key对应的索引,将值存到索引对应的数据区中。
获取数据时,通过哈希函数计算出key对应的索引,取出索引位置对应的数据。
由于需要哈希函数计算,所以key值必须是可哈希的,也就是说key值必须是不可变的类型
python中不可变数据类型为:字符串,数字,元组(元素为不可变类型),函数,类对象

哈希表存储

hash表利用hash函数计算出Key的哈希值,与数组长度求余,取余结果index作为数组下标
list[hash(key)%len(list)]=value

三,哈希冲突与扩容

只要样本足够大,任何哈希函数一定会出现两个不同的key得出同一个哈希值,此时会出现两个不同key存入同一个数组位置,这种就称为哈希冲突。
可以利用开链法和开发寻址法解决冲突。

开链法:哈希表中的顺序表的每个位置存储的是链表,如果发生冲突时,冲突的元素会被加在链表的后面
开发寻址法:如果发现index位置上有数据,则探查新的位置来存储,index有值,则探查index+n 以此类推
主流编程语言的哈希冲突算法为开链法,比如java,python。

负载因子 表示散列表的装满程度       元素个数/散列表长度
当哈希表的存储位置存满后将会自动扩容,但是会在负载因子达到一定阈值时,
就会开始扩容,每次扩容大小为原来的两倍,java,python哈希表负载因子默认为0.75

四,手写字典

简单版字典

class myDict:
    def __init__(self,max):
        self.max=max
        self.hashTable=[None for _ in range(max)]
    def addItem(self,key,value):
        """增加"""
        index=hash(key)%self.max
        self.hashTable[index]=value
    def getValue(self,key):
        index=hash(key)%self.max
        return self.hashTable[index]
mydict=myDict(20)
mydict.addItem("key1",100)
mydict.addItem("key1",200)
mydict.addItem("key2",300)
print(mydict.getValue("key1"))
print(mydict.getValue("key2"))
print(mydict)

模拟哈希冲突

class myDict:
    def __init__(self,max):
        self.max=max
        self.hashTable=[None for _ in range(max)]
        self.capacity=0
    def addItem(self,key,value):
        """增加"""
        if self.capacity==self.max:
            raise Exception("超出容量")
        index=hash(key)%self.max
        if self.hashTable[index]:
            raise Exception(f"哈希冲突")
        self.hashTable[index]=value
        self.capacity+=1
    def getValue(self,key):
        index=hash(key)%self.max
        return self.hashTable[index]

"""模拟哈希冲突"""
mydict=myDict(100)
temp=['q','w','e','r','t','y','u','i','o']
result=[]
for x in temp:
    for y in temp:
        for z in temp:
            result.append(f"{x}{y}{z}")

for item in result:
    mydict.addItem(item,f"{item}-value")

解决哈希冲突版字典

#编写链表数据结构
class Node:
    """一个简单的链表子节点"""
    def __init__(self,key,value):
        self.key=key
        self.value=value
        self.next=None
class myDict:
    def __init__(self,max):
        self.max=max
        self.hashTable=[None for _ in range(max)]
        self.capacity=0
    def addItem(self,key,value):
        """增加"""
        if self.capacity==self.max:
            raise Exception("超出容量")
        index=hash(key)%self.max
        if self.hashTable[index]:
            print(f"hash冲突 {key} {value}")
            node=self.hashTable[index]
            while node.next:
                node=node.next
            node.next=Node(key,value)
        else:
            self.hashTable[index]=Node(key,value)
            self.capacity+=1
    def getValue(self,key):
        flag=False
        index=hash(key)%self.max
        node=self.hashTable[index]
        if not node:
            raise Exception("key error 1 ")
        elif node.key==key:
            return node.value
        else:
            while node.next:
                node = node.next
                if node.key==key:
                    flag=True
                    break
        if not flag:
            raise Exception("key error 2 ")
        return node.value

mydict=myDict(20)
temp=['q','w','e','r','t','y','u','i','o','a','s','d','f','g','h','j','k','z','x','c','v','b','n']
result=[]
for x in temp:
    for y in temp:
        for z in temp:
            result.append(f"{x}{y}{z}")

for item in result:
    mydict.addItem(item,f"{item}-value")
print(mydict)

自动扩容版字典

class Node:
    """一个简单的链表子节点"""
    def __init__(self,key,value):
        self.key=key
        self.value=value
        self.next=None
class myDict:
    def __init__(self,max):
        self.max=max
        self.hashTable=[None for _ in range(max)]
        self.capacity=0
    def addItem(self,key,value):
        """增加"""
        """判断是否需要扩容"""
        factor=self.capacity/self.max
        if factor>0.75:
            self.hashTable.extend([None for _ in range(self.max)])
            self.max=self.max*2
        index=hash(key)%self.max
        if self.hashTable[index]:
            print(f"hash冲突 {key} {value}")
            node=self.hashTable[index]
            while node.next:
                node=node.next
            node.next=Node(key,value)
        else:
            self.hashTable[index]=Node(key,value)
        self.capacity+=1
    def getValue(self,key):
        flag=False
        index=hash(key)%self.max
        node=self.hashTable[index]
        if not node:
            raise Exception("key error 1 ")
        elif node.key==key:
            return node.value
        else:
            while node.next:
                node = node.next
                if node.key==key:
                    flag=True
                    break
        if not flag:
            raise Exception("key error 2 ")
        return node.value

mydict=myDict(20)
temp=['q','w','e','r','t','y','u','i','o','a','s','d','f','g','h','j','k','z','x','c','v','b','n']
result=[]
for x in temp:
    for y in temp:
        for z in temp:
            for k in temp:
                for t in temp:
                    result.append(f"{x}{y}{z}{k}{t}")

for item in result:
    mydict.addItem(item,f"{item}-value")

print(mydict)
  • 24
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python字典底层实现的是哈希表。哈希表是一种数据结构,它通过哈希函数将键(key)转换成唯一的地址(索引),然后将值(value)存储在对应的地址中。Python内置的哈希函数会对键进行哈希运算和取余运算,以获得唯一的地址。当多个键经过哈希运算后得到相同的地址时,会发生哈希碰撞,Python会使用开放定址法或链表法来解决碰撞问题。对于相同的键,后面的赋值操作会直接覆盖前面的值,因为它们会计算得到相同的地址。因此,Python字典的底层实现是基于哈希表的。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【pythonpython字典的底层是怎么实现的](https://blog.csdn.net/YZL40514131/article/details/125349175)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [详解Python字典底层原理——哈希表(Python面试必备)](https://blog.csdn.net/qq_42815145/article/details/91353624)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值