字典
字典是“键值对”的无序可变序列,字典中的每个元素都是一个“键值对”,包含:“键对象”和“值对象”。可以通过“键对象”实现快速获取、删除、更新对应的“值对象”。
列表中我们通过“下标数字”找到对应的对象。字典中通过“键对象”找到对应的“值对象”。“键”是任意的不可变数据,比如:整数、浮点数、字符串、元组。但是:列表、字典、集合这些可变对象,不能作为“键”。并且“键”不可重复。“值”可以是任意的数据,并且可重复。
一个典型的字典的定义方式:a = {'name':'LQQ','age':18,'job':'programmer'}
一、字典的创建
1、通过 {} 和 dict() 函数创建字典
a={"name":"LQQ","age":"24","job":"programmer"}
a
>>>{'name': 'LQQ', 'age': '24', 'job': 'programmer'}
b=dict(name="LQQ",age="24",job="programmer")
b
>>>{'name': 'LQQ', 'age': '24', 'job': 'programmer'}
c=dict([("name","age"),("LQQ","24")])
c
>>>{'name': 'age', 'LQQ': '24'}
d={}
d
>>>{}
e=dict()
e
>>>{}
2、通过zip()创建字典对象
k=["name","age","job"]
j=["LQQ",24,"programmer"]
a=dict(zip(k,j))
a
>>>{'name': 'LQQ', 'age': 24, 'job': 'programmer'}
3、通过fromkeys创建值为空的字典
a=dict.fromkeys(["name","age","job"])
a
>>>{'name': None, 'age': None, 'job': None}
二、字典的访问
1、通过 [键] ,获得 [值] ,若不存在返回异常
a={"name":"LQQ","age":"24","job":"programmer"}
a
>>>{'name': 'LQQ', 'age': '24', 'job': 'programmer'}
a["name"]
>>>'LQQ'
2、通过get()方法获取值,指定键不存在时,返回None
a={"name":"LQQ","age":"24","job":"programmer"}
a
>>>{'name': 'LQQ', 'age': '24', 'job': 'programmer'}
a.get('name')
>>>'LQQ'
a.get("sex")
>>>
print(a.get("sex"))
>>>None
a.get("sex","meiyou")
>>>'meiyou' #如果你想让它不存在时返回你想要的字符串,可以这样设定。
3、列出所有键值对 items()
a.items()
>>>dict_items([('name', 'LQQ'), ('age', '24'), ('job', 'programmer')])
4、列出所有的键 keys(),列出所有的值 values()
a.keys()
>>>dict_keys(['name', 'age', 'job'])
a.values()
>>>dict_values(['LQQ', '24', 'programmer'])
5、列出键值对的个数 len()
a={"name":"LQQ","age":"24","job":"programmer"}
len(a)
>>>3
6、检测一个“键”是否在字典中
a={"name":"LQQ","age":"24","job":"programmer"}
"name" in a
>>>True
三、字典元素的添加、修改和删除
1、给字典新增“键值对”时如果“键”已经存在,则覆盖旧的键值对,如果“键”不存在,新增“键值对”
a={"name":"LQQ","age":"24","job":"programmer"}
a["address"]="天津"
a
>>>{'name': 'LQQ', 'age': '24', 'job': 'programmer', 'address': '天津'}
a["age"]=18
a
>>>{'name': 'LQQ', 'age': 18, 'job': 'programmer', 'address': '天津'}
2、使用update()将新字典中所有键值对全部添加到旧字典对象上,如果重复直接覆盖。
a={'name': 'LQQ', 'age': 18, 'job': 'programmer', 'address': '天津'}
n={"name":"LQQ","age":"18","job":"programmer","money":10000}
a.update(n)
a
>>>{'name': 'LQQ', 'age': '18', 'job': 'programmer', 'address': '天津', 'money': 10000}
3、字典中元素的删除可以使用 del()方法,或者 clear()删除所有键值对,pop()删除指定键值对,并返回对应的“值对象”。
a={'name': 'LQQ', 'age': '18', 'job': 'programmer', 'address': '天津', 'money': 10000}
del(a["name"])
a
>>>{'age': '18', 'job': 'programmer', 'address': '天津', 'money': 10000}
a.pop("age")
>>>'18'
a
>>>{'job': 'programmer', 'address': '天津', 'money': 10000}
a.clear()
a
>>>{}
4、popitem() :随机删除和返回该键值对,可以用于遍历整个字典
字典是“无序可变序列”,因此没有第一个元素、最后一个元素的概念;popitem 弹出随机的项,因为字典并没有"最后的元素"或者其他有关顺序的概念。若想一个接一个地移除并处理项,这个方法就非常有效(因为不用首先获取键的列表)。
a={'name': 'LQQ', 'age': '18', 'job': 'programmer', 'address': '天津', 'money': 10000}
a.popitem()
>>>('money', 10000)
a.popitem()
>>>('address', '天津')
a
>>>{'name': 'LQQ', 'age': '18', 'job': 'programmer'}
四、序列解包
序列解包可以用于元组、列表、字典。序列解包可以让我们方便的对多个变量赋值。
x,y,z=(10,20,30)
(a,b,c)=(10,20,30)
[a,b,c]=(10,20,30)
序列解包用于字典时,默认是对“键”进行操作,如果需要对键值对操作,则需要使用items(),如果需要对“值”进行操作,则需要使用 values()
a={'name': 'LQQ', 'age': '18', 'job': 'programmer', 'address': '天津', 'money': 10000}
name,age,job,address,money=a
name
>>>'name'
age
>>>'age' #默认对键进行操作
name,age,job,address,money=a.items()
name
>>>('name', 'LQQ') #对键值对进行操作
name,age,job,address,money=a.values()
name
>>>'LQQ' #对值进行操作
练习:表格数据使用字典和列表存储,并实现访问
r0={"name":"LQQ","age":24,"money":10000,"city":"北京"}
r1={"name":"LYY","age":23,"money":20000,"city":"上海"}
r2={"name":"LAA","age":25,"money":30000,"city":"江苏"}
tb=[r0,r1,r2]
#获得第二行人的薪资
print(tb[1].get("money"))
#打印列表中所有人的薪资
for i in range(len(tb)):
print(tb[i].get("money"))
#打印列表中所有的数据
for i in range(len(tb)):
print(tb[i].get("name"),tb[i].get("age"),tb[i].get("money"),tb[i].get("city"))
>>>
20000
10000
20000
30000
LQQ 24 10000 北京
LYY 23 20000 上海
LAA 25 30000 江苏
五、字典核心底层原理(重要)
字典对象的核心是散列表。散列表是一个稀疏数组(总是有空白元素的数组),数组的每个单元叫做 bucket。每个 bucket 有两部分:一个是键对象的引用,一个是值对象的引用。由于,所有 bucket 结构和大小一致,我们可以通过偏移量来读取指定 bucket。
假设字典 a 对象创建完后,数组长度为 8,我们要把”name”=”gaoqi”这个键值对放到字典对象 a 中,首先第一步需要计算键”name”的散列值。Python 中可以通过 hash()来计算。
>>> bin(hash("name"))'-0b1010111101001110110101100100101
由于数组长度为 8,我们可以拿计算出的散列值的最右边 3 位数字作为偏移量,即“101”,十进制是数字 5。我们查看偏移量 5,对应的 bucket 是否为空。如果为空,则将键值对放进去。如果不为空,则依次取右边 3 位作为偏移量,即“100”,十进制是数字4。再查看偏移量为 4 的bucket 是否为空。直到找到为空的 bucket 将键值对放进去。流程图如下:
扩容:接近 2/3 时,数组就会扩容python 会根据散列表的拥挤程度扩容。“扩容”指的是:创造更大的数组,将原有内容拷贝到新数组中。
读取数据:与存储数据算法一样,get(key),计算key的hash值,与上述hash值对比,两数相等时,认为找到了,读取value。
集合
集合是无序可变,元素不能重复。实际上,集合底层是字典实现,集合的所有元素都是字典中的“键对象”,因此是不能重复的且唯一的。
一、集合的创建和删除
1、使用 {} 创建集合对象,并使用 add() 添加元素
a={1,2,3}
a
>>>{1,2,3}
a.add(4)
a
>>>{1,2,3,4}
2、使用 set() 将列表、元组等可迭代对象转成集合,重复数据只保留一个
a=["a","b","c","b"]
b=set(a)
b
>>>
{'a', 'c', 'b'}
3、remove() 删除指定元素,clear() 清空整个集合
b={'a', 'c', 'b'}
b.remove("a")
b
>>>{'c', 'b'}
b.clear()
b
>>>{}
4、集合的交并补
a = {1,3,'sxt'}
b = {'he','it','sxt'}
a|b #并集
>>>{1, 3, 'sxt', 'he', 'it'}
a&b #交集
>>>{'sxt'}
a-b #差集
>>>{1, 3}
a.union(b) #并集
>>>{1, 3, 'sxt', 'he', 'it'}
a.intersection(b) #交集
>>>{'sxt'}
a.difference(b) #差集
>>>{1, 3}