Python字典

字典是键值对的无序可变序列,字典中的每个元素都是一个键值对,包含键对象和值对象。可以通过键对象实现快速获取、删除、更新对应的值对象。

字典的创建
  1. 通过{}、dict()来创建字典对象

a = {'name':'CSDN','age':18,'job':'程序猿'}
# a = {'name': 'CSDN', 'age': 18, 'job': '程序猿'}
b = dict(name='CSDN',age=18,job='程序员')
# b = {'name': 'CSDN', 'age': 18, 'job': '程序员'}
e = dict([("name","gaoqi"),("age",18)])
# e = {'name': 'gaoqi', 'age': 18}
c = {} #空的字典对象
# c = {}
d = dict() #空的字典对象
# d = {}
  1. 通过zip()创建字典对象

k = ['name','age','job']
v = ['CSDN',18,'程序员']
d = dict(zip(k,v))
print(d) #{'name': 'CSDN', 'age': 18, 'job': '程序员'}
  1. 通过fromkeys创建值为空的字典

f = dict.fromkeys(['name','age','job'])
print(f) #结果:{'name': None, 'age': None, 'job': None}

字典元素的访问
  1. 通过键获得值,若不存在,则抛出异常

a = {'name':'CSDN','age':18,'job':'程序猿'}
b = a['name']
print(b)    # CSDN
  1. 通过get()方法获得值。推荐使用,优点:如果指定的键不存在,返回None;也可以设定指定键不存在时默认返回的对象。

a = {'name':'CSDN','age':18,'job':'程序猿'}
b = a.get('name')
c = a.get('gender')
d = a.get('address','China')
print(b)    # CSDN
print(c)    # None
print(d)    # China
  1. 列出所有的键值对

a = {'name':'CSDN','age':18,'job':'程序猿'}
b = a.items()
print(b)    # dict_items([('name', 'CSDN'), ('age', 18), ('job', '程序猿')])
  1. 列出所有的键,列出所有的值

a = {'name':'CSDN','age':18,'job':'程序猿'}
k = a.keys()
v = a.values()
print(k)    # dict_keys(['name', 'age', 'job'])
print(v)    # dict_values(['CSDN', 18, '程序猿'])
  1. len()键值对的个数

a = {'name':'CSDN','age':18,'job':'程序猿'}
print(len(a))    # 3
  1. 检测一个键在字典中是否存在

a = {'name':'gaoqi','age':18,'job':'programmer'}
print("name" in a)    #True
print("gender" in a)    # False

字典元素添加、修改、删除
  1. 给字典新增键值对。如果键已经存在,则覆盖旧的键值对。如果键不存在,则新增键值对

a = {'name':'CSDN','age':18,'job':'程序猿'}
a['address']='China'
a['age']=20
print(a) 
#{'name': 'CSDN', 'age': 20, 'job': '程序猿', 'address': 'China'}
  1. 使用update()将新字典中所有键值对全部添加到就字典对象上。如果key有重复,则直接覆盖

a = {'name':'CSDN','age':18}
b = {'name':'竹筒饭','gender':'男'}
a.update(b)
print(a)    # {'name': '竹筒饭', 'age': 18, 'gender': '男'}
print(b)
  1. 字典中的元素的删除,可以使用del()方法;或者clear()删除所有键值对;pop()删除指定键值对,并返回对应的值对象。

a = {'name':'CSDN','age':18}
del(a['name'])
print(a)    # a = {'age':18}

age = a.pop('age')
print(age)    # 18
  1. popitem() :随机删除和返回该键值对。字典是“无序可变序列”,因此没有第一个元素、最后一个元素的概念;popitem弹出随机的项,因为字典并没有"最后的元素"或者其他有关顺序的概念。若想一个接一个地移除并处理项,这个方法就非常有效。

a = {'name':'CSDN','age':18,'job':'程序员'}
r1 = a.popitem()
print(r1)        # ('job', '程序员')
r2 = a.popitem()
print(r2)        # ('age', 18)
r3 = a.popitem()
print(r3)        # ('name', 'CSDN')
print(a)        # {}

序列解包

序列解包可用于元组、列表、字典。序列解包可以让我们方便的对多个变量赋值

x,y,z=(20,30,10)
(a,b,c)=(9,8,10)
[m,n,p]=[10,20,30]

序列解包用于字典时,默认是对“键”进行操作; 如果需要对键值对操作,则需要使用items();如果需要对“值”进行操作,则需要使用values();

s = {'name':'CSDN','age':18,'job':'程序员'}
name,age,job=s
print(name)    # name
name,age,job=s.items()
print(name)    # ('name', 'gaoqi')
name,age,job=s.values()
print(name)    # CSDN

字典核心底层原理(存储键值对的过程)

字典对象的核心时散列表。散列表是一个稀疏数组(总是有空白元素的数组),数组的每个单元叫做bucket。每个bucket有两部分:一个是键对象的引用,一个是值对象的引用。由于所有bucket结构和大小一致,我们可以通过偏移量俩读取指定bucket。

将一个键值对放进字典的底层过程

a = {}
a["name"]="竹筒饭"

假设字典a对象创建完后,数组长度为8:

把“name” = “竹筒饭”这个键值对放到字典对象a中,首先第一步需要计算键“name”的散列值。Python中通过hash()计算。

>>> bin(hash("name"))
'-0b1010111101001110110101100100101'

由于数组长度为8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即“101”,十进制是数字5。查看偏移量5对应的bucket是否为空。如果为空,则将键值对放进去,如果不为空,则依次取左边3位作为偏移量,即“100”,十进制是数字4。再查看偏移量为4的bucket是否为空。直到找到为空的buckrt将键值对放进去。

Python会根据散列表的拥挤层度扩容。扩容就是创造更大的数组,将原有内容拷贝到新数组中。

接近2/3时,数组就会扩容。

字典核心底层原理(查找键值对的过程)

和存储的底层流程算法一致,也是依次取散列值的不同位置的数字。假设数组长度为8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即101,十进制是数字5,查看对应的bucket是否为空。如果为空,则返回None。如果不为空,则将计算这个bucket的键对象的散列值,进行比较,如果相等则将对应的值对象负担会,如果不相等则再一次取其他几位数字,重新计算偏移量。依次取完后,仍然没有找到则返回None。

用法总结

  • 字典在内存中开销巨大,典型的空间换时间。

  • 键查询速度很快

  • 往字典里面添加新键值对可能导致扩容,导致散列表中键的次序变化。因此,不要在遍历字典的同时进行字典的修改

  • 键必须可散列

  • 数字、字符串、元组,都是可散列的

  • 自定义对象需要支持下面三点:

  • 支持hash()函数

  • 支持通过__eq__()方法检测相等性

  • 若a==b为真,则hash(a)==hash(b)也为真

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值