字典
字典是“键值对”的无序可变序列。键是任意不可改变的的数据,键不可重复。值是可以重复的。
一个典型字典的定义方式:{“name”:"grace,“age”:18}
字典的创建:
- dict()和{}
空对象:a = dict()
a = {}
b = dict(name="grace", age=18, job="student")
print(b)
c = dict([("name","grace"),("age",18)]) # 列表中含有两个元组
print(c)
- 通过dict(zip())创建字典对象(zip也可用于将原有列表组成列表中套元组的形式)
k = ["name", "age", "job"]
v = ["grace", 18, "student"]
a = dict(zip(k, v)) #本质还是列表中有两个元组
print(a)
- 通过dict.fromkeys()创建值为空的字典
a = dict.fromkeys(["name", "age", "job"]) # 需要列表的形式
print(a)
字典元素的访问
- 通过键获得值,若值不存在,则抛出异常
- 通过get()方法获得“值”,推荐使用。优点:指定键不存在时,返回None
- 列出所有的键值对a.items()
- 列出所有的键,列出所有的值 a.keys() a.values()
- len()键值对的个数
- 检测一个键是否在字典中 in
b = dict(name="grace", age=18, job="student")
print(b["name"])
print(b.get("name"))
print(b.get("gender"))
print(b.get("gender", "不存在")) # 修改None默认值为不存在
print(b.items())
print(b.keys())
print(b.values())
print(len(b)) # b是在len()中的
print("job" in b)
字典元素添加修改删除
- 给字典新增键值对。如果"键"已经存在,则覆盖旧键。如果键原本不存在,则增加新键值对。
a[""]=
a[“address”] = “China” - 使用update()将新字典中所有键值对全部添加到旧字典对象上,如果key有重复,则直接覆盖
a = {}
b = {}
a.update(b) - 字典中元素的删除,可以使用del(a[""])的方法,或者a.clear()删除所有键值对,pop("")删除指定键值对,并返回“值对象”(b = a.pop("")
- popitem()随机删除并返回该键值对。字典是“无序可变序列”,因此没有第一个元素,最后一个元素的概念;popitem()弹出随机的项。若想一个接一个移除并处理项,这个方法就非常有效。
b = a.popitem()
b = dict(name="grace", age=18, job="student")
b["address"] = "China"
print(b)
a = {"company":"sxt", "location":"北京", "job":"teacher"}
b.update(a) # 用a的内容更新并覆盖b,对b进行修改
print(b)
del(b["address"])
print(b)
c = b.pop("company")
print(c) # 返回company对应的键值sxt
print(b)
d = b.popitem()
print(d)
print(b)
b.clear()
print(b)
序列解包
序列解包可用于元组,列表,字典。解包序列可以让我们方便地对多个量进行赋值。
序列解包用于字典时,默认对键进行操作,如果对键值进行操作,则需要使用values(),如果对键值对进行操作,则使用items()。
e = dict(name="grace", age=18, job="student")
a, b, c = e
print(a)
f, g, h = e.values()
print(g)
s, t, u = e.items()
print(u)
d, f = (9, 10)
print(d)
练习:(用字典和列表形式制作表格)
a = dict(name="Grace", age=18, salary=1800, location="ON")
b = dict(name="Lisa", age=19, salary=1700, location="QC")
c = dict(name="Nancy", age=17, salary=1900, location="BC")
tb = [a, b, c] # 第一行,第二行,第三行
print(tb[1].get("salary")) #第一行取salary对应的键值
for i in range(len(tb)):
print(tb[i].get("salary"))
for i in range(len(tb)):
print(tb[i].get("name"), tb[i].get("age"), tb[i].get("salary"),tb[i].get("location"))
字典核心底层原理
字典对象的核心是散列表。散列表是一个稀疏数组,数组的每个单元叫做bucket。么个bucket有两部分,一个是键,一个是值。
由于每个bucket大小和结构一样,我们可以通过偏移量来读取指定的bucket。
将一个键值对放进字典的底层过程:
a = {}
a["name"] = "grace"
print(a)
print(bin(hash("name"))) # 0b101001111010010100111100110001011010001111001101010010011001001
第一步计算键"name"的散列值,python中可以使用hash()来计算
b = bin(hash(“name”)))
假设数组长度为8。我们可以拿计算出的散列值的最右边三位数字作为偏移量,即"101",十进制数字为5.我们查看偏移量5,若对应的bucket为空,则将键值对放入,若不为0,则依次取左边三位作为偏移量,十进制为4。直到找到空的bucket将键值对放进去。
根据键查找键值对的过程:
第一步是要计算"name"对象的散列值:bin(hash(“name”))
用法总结:
- 键必须散列:数字,字符串,元组都是可散列的。
自定义对象需要满足以下三点:
- 支持hash()函数
- 支持通过__eq__()的方法检测相等性
- 若a == b, hash(a) == hash(b)
- 字典在内存中开销巨大,典型的空间换时间
- 键查询速度很快
- 往字典里添加新建内容可能导致扩容,导致散列表中键的次序发生变化。因此,不要在遍历字典的同时进行修改
集合
集合是无序可变的,元素不能重复。实际上,集合底层是字典实现的,集合所有元素都是字典中的键对象,因此是不能重复且唯一的。
集合的创建和删除
- 使用{}创建对象,使用a.add()添加元素(不可添加已有元素)
- 使用set(),将列表,元组等可迭代对象转化为集合。如果原来数据存在重复数据,那么只保留一个。(b = set(a))
- 使用a.remove()删除指定元素,a.clear()清除整个集合。
集合相关操作
并集(|或a.union()),交集(&或a.intersection()),差集(-或a.difference())差集是a减去交集的那部分
a = {1, 2, 3}
b = (6, "sxt", 8)
a.add("school")
print(a)
print(set(b))
print(a|set(b))
控制语句
选择结构
选择结构通过判断条件是否成立,来决定执行哪个分支。
选择结构有多种形式:单分支,双分支,多分支
单分支选择结构
if 条件表达式:
(缩进)语句块
a = input("请输入一个数字:")
if int(a)>10: #将a由string转化成integer
print(a)
在选择和循环结构中,条件表达式的值为false的情况如下:
False,0,空值None,空字符串,空序列对象,空range对象,空迭代对象
b = []
if b:
print("输入空列表为false")
else:
print("false")
条件表达式中不能有赋值符“=”
双分支选择结构
if 条件表达式:
(缩进)语句块
else:
(缩进)语句块
三元条件运算符
三元条件运算符格式如下:
条件为真时的值 if(条件表达式) else 条件为假时的值
a = input('请输入一个数:')
print(a if int(a)<100 else "数字太大")
多分支选择结构
if 条件表达式1:
语句块1
elif 条件表达式1:
语句块2
.
.
.
else:
语句块n
score = input('请输入分数:')
grade = ""
if int(score) < 60:
grade = "不及格"
elif int(score) < 80:
grade = "及格"
elif int(score) < 90:
grade = "良好"
elif int(score) < 100 or int(score) == 100:
grade = "优秀"
else:
print('请重新输入分数') #有缺点是输入大于100的数时,还会print分数
print("分数是{0},等级是{1}".format(score, grade))
选择结构的嵌套(通过缩进来实现)
score = input('请输入分数:')
grade = ""
if int(score) > 100 or int(score)<0:
score = input("输入错误,请重新输入")
else:
if int(score) < 60:
grade = "不及格"
elif int(score) < 80:
grade = "及格"
elif int(score) < 90:
grade = "良好"
else:
grade = "优秀"
print("分数是{0},等级是{1}".format(score, grade)) # print也要缩进,使得它属于else
score = int(input('请输入分数:'))
grade = "ABCDE"
num = 0
if score > 100 or score < 0:
score = int(input("输入错误,请重新输入"))
else:
num = score//10
if num<6:
num = 5
elif num == 10:
num = 9 # 考虑100的特殊情况
print("分数是{0},等级是{1}".format(score, grade[9-num])) # print也要缩进,使得它属于else
循环结构
循环结构用于重复执行一条或多条语句。表达这样的逻辑,如果符合条件,则反复执行循环体力的语句。
while语句:
num = 0
while num<= 10:
print(num, end="\t")
num += 1
num = 0
sum_num = 0
while num <= 10:
sum_num = num + sum_num
num += 1
print(sum_num, end="\t")