Python基础第四节

字典

字典是”键值对“的无序可变序列,其中每个元素都是一个”键值对“,包含”键对象“和”值对象“。
就像可通过列表元素索引值获取对应对象,我们可通过”键对象“获取、删除、更新其对应的值对象。
键必须是不可变数据,如整数、浮点数、字符串、元组,不能是字典、列表、集合等可变对象,
键不可重复。若重复出现键,则后面的覆盖前面的。

字典的创建

方法1:
a={‘a’:‘bc’,‘d’:‘fg’}
b=dict(a=‘bc’,d=‘fg’)
c=dict([(‘a’,‘bc’),(‘d’,‘fg’)])
d={}或d=dict()
方法2:
通过zip()创建。如:
k=[‘a’,‘d’]
v=[‘bc’,‘fg’]
d=dict(zip(k,v))
d={‘a’:‘bc’,‘d’:‘fg’}
方法3:
通过fromkeys()创建值为空的字典
a=dict.fromkeys([‘a’,‘d’])
a: {‘a’:None,‘d’:None}

字典元素的访问

a={‘a’:‘bc’,‘d’:‘fg’}
方法1:
通过键,获取值。若值不存在,则抛出异常。
a[‘a’]: ‘bc’
a[‘d’]: ‘dg’
方法2:
get()方法。若指定键不存在则返回None。也可指定键不存在时默认返回的对象。推荐使用该函数。
a.get(‘a’): ‘bc’
a.get(‘haha’): None
a.get(‘haha’,‘好人’): ‘好人’
方法3:
items()方法,获取所有键值对。
a.items(): dict_items([(‘a’,‘bc’),(‘d’,‘fg’)])
方法4:
keys()方法,列出所有的键。
a.keys(): dict_keys([‘a’,‘b’])
values()方法,列出所有的值
a.values(): dict_values([‘bc’,‘fg’])
方法5:
len(a),返回键值对的个数
方法6:
检测一个键是否在字典中。
‘a’ in a: True

字典元素添加、修改、删除

方法1:
给字典新增键值对。若新增的”键“不存在,则新增键值对;若”键“已存在,则覆盖先前的键值对。
若a[‘abc’]=‘def’
a: {‘a’:‘bc’,‘d’:‘fg’,‘abc’:‘def’}
若a[‘a’]=‘mn’
a: {‘a’:‘mn’,‘d’:‘fg’}
方法2:
a.update(b): 将b字典中所有键值对都添加进a字典。若键有重复,则直接覆盖。
方法3:
字典中元素删除:
del()方法:del(a[‘a’]),删除以’a’为键的键值对。
a.clear(): 删除所有键值对
a.pop(‘a’): 删除指定键值对,并返回’a’对应的值对象’bc’
a.popitem(): 随即删除和返回某键值对。
若想一个一个地移除并处理项,此方法很有效,
因为不需要首先获取键的列表。

序列解包

序列解包可用于列表、元组、字典。可方便地对多个变量赋值。
(x,y,z)=(20,30,10)
x,y,z=(20,30,10)
[x,y,z]=[20,30,10]
序列解包用于字典时,默认是对键进行操作。如:
a={‘a’:‘bc’,‘d’:‘fg’}
x,y=a: x=‘a’, y=‘d’
若需对键值对进行操作,则:
x,y=a.items():x=(‘a’,‘bc’), y=(‘d’,‘fg’)
若需对值进行操作,则:
x,y=a.values():x=‘bc’,y=‘fg’

表格数据使用字典和列表存储并访问

Python基础第四节
r1={‘name’:‘高小一’,‘age’:18,‘salary’:30000,‘location’:‘北京’}
r2={‘name’:‘高小二’,‘age’:19,‘salary’:20000,‘location’:‘上海’}
r3={‘name’:‘高小五’,‘age’:20,‘salary’:10000,‘location’:‘深圳’}
tb=[r1,r2,r3]
#获得第二行的人的薪资:
tb[1].get(‘salary’)

字典核心底层原理

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

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

假设字典对象创建完成后,数组长度为8。
要将某键值对放进字典对象:
第一步是计算键的散列值(哈希值),用hash()方法计算。
第二步是拿计算出的散列值的最后三位数字对应的十进制数作为偏移量,并查看该偏移量对应的bucket是否为空。若为空,就存入;若非空,则再取倒数第二组三位数字对应的十进制数作为偏移量。以此类推,直到找到空的bucket。
(一组取几位数字,与数组当前长度有关。8对应四位二进制数,则取3位;32对应6位二进制数,则取5位)
扩容:
python会根据散列表的拥挤程度扩容。若数组空间已占用接近2/3,则将创建新数组并将原有内容拷贝进新数组。

根据键查找键值对的底层过程

第一步是计算用于查找的键的散列值;
第二步是取散列值最后n位二进制数(n与数组长度相关),并进制转换得到索引值;
第三步是检查该索引值对应的bucket是否为空。若为空,则返回None;若不为空,则取出bucket中的键并计算其散列值,与用于查找的键的散列值对比;
第四步是若两散列值相等,则返回这个bucket中的值对象;若不相等,则再取散列值的倒数第二组数,得到新的索引值并查找、对比。以此类推。
Python基础第四节

字典用法总结

键必须可散列:
1.数字、字符串、元组均为可散列;
2.若要自定义键对象,则须满足以下几点:
(1)支持hash()函数;
(2)支持通过__eq__()方法检查相等性
(3)满足若a==b,则hash(a)==hash(b)
用空间换时间:
字典占用内存巨大,但用键查询速度很快。
不要在遍历字典时进行字典修改:
往字典里添加新键可能导致扩容,使散列表中键的次序变化。若需修改字典,应先遍历、提取所需元素,然后修改。

集合

集合是无序可变序列,且其中元素不能重复。
集合的底层是字典实现,其所有元素都是字典中的键对象。

集合创建、增加和删除

创建: a={1,3,4}
或b=[1,3,4], set(b)
set()可将列表、元组等可迭代对象转换为集合。若原对
象存在重复数据,则只保留一个。
增加:a.add(x)
删除:a.remove(x), 删除指定元素x
a.clear(): 清空整个集合

集合相关操作

a|b a.union(b) 并集
a&b a.intersection(b) 交集
a-b a.difference(b) 差集

条件表达式

单分支结构:
若条件表达式为True,则执行语句块;
否则,跳过语句块,继续执行。
▲在选择和循环结构中,条件表达式值为False的情况有:
False, 0, 0.0, 空值None,空序列对象,空range对象,空迭代对象
除以上情况外,条件表达式值均为True。
因此,Python中所有合法的表达式均可看作条件表达式,甚至包括函数调用的表达式。
双分支结构:
条件表达式为True,执行语句块1;
条件表达式为False,执行语句块2.
对简单的双分支赋值情况,可使用三元条件运算符,如:
print(num if num<10 else ‘数字太大’)
多分支结构
循环结构:
循环结构用于反复执行一条或多条语句。
若符合条件,则执行循环体中的语句。每次执行完,都再判断一遍条件是否为True。若为True,则继续执行循环体中的语句;若为False,则跳出循环。
循环体中的语句应至少包含改变条件表达式的语句,以使循环能趋于结束