43.字典_特点_4种创建方式_普通_dict_zip_formkeys
字典简介和特点
字典是“键值对”的无序可变序列,字典中的毎个元素都是一个“键值对”,包含:"键对象”和“值对象”。可以通过“键对象”实现快速获取、删除、更新对应的“值对象“。
列表中我们通过“下标数字”找到对应的对象。字典中通过“键对象”找到对应的“值对象”·“键”是任意的不可变数据,比如:整数、浮点数、字符串、元组。
但是,列表、字典、集合这些可变对象,不能作为“键”。只能是不可变对象。
“键”不可重复,“值”可以是任意的数据,并且可重复。
一种典型的字典定义方式:
a = {‘name’:‘daxian’, ‘age’:18, ‘job’:‘teacher’}
4种创建字典方式
{}、
我们可以通过{}、dct{}来创建字典对象
>>> a = {'name':'daxian', 'age':18, 'job':'teacher'}
#生成空字典
>>>> d = {}
dict()
>>> b = dict(name = 'daxian', age =18, job = 'teacher')
>>> c = dict( [('name','daxian'),('age',18),('job','teacher')] )
>>>>> f = dict()
zip()
我们可以通过zip()来创建字典对象
>>> k =['name','age','job']
>>> v = ['daxian',18,'teacher']
>>> a = dict(zip(k,v))
>>> a
{'name': 'daxian', 'age': 18, 'job': 'teacher'}
fromkeys(list)
通过 fromkeys创建 值为空的字典
>>> a = dict.fromkeys(['name','age','job'])
>>> a
{'name': None, 'age': None, 'job': None}
44.字典_元素的访问_键的访问_值的访问_键值对的访问.
为了测试各种访问方法,我们这里设定一个字典对象:
a = {‘name’:‘gaoqi’,‘age’:18,‘job’:‘programmer’}
1.通过[键]获得“值”。
若键不存在,则抛出异常。
>>> a = {'name':'daxian','age':18,'job':'teacher'}
>>> a['name']
'daxian'
>>> a['age']
18
>>> a['sex']
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
a['sex']
KeyError: 'sex'
2.通过get()方法获得“值”。
推荐使用。优点是:指定键不存在,返回None;也可以设定指定键不存在时默认返回的对象。-推荐使用get()获取“值对象
>>> a.get('name')
'daxian'
>>> a.get('ddd') #键不存在时,返回none
>>>
>>> print(a.get('ddd'))
None
>>> a.get('ddd','不存在')
'不存在'
3.列出所有的键值对
>>> a.items()
dict_items([('name', 'daxian'), ('age', 18), ('job', 'teacher')])
4.列出所有的键,列出所有的值
>>> a.keys()
dict_keys(['name', 'age', 'job'])
>>> a.values()
dict_values(['daxian', 18, 'teacher'])
5.len()键值对的个数
>>> len(a)
3
6.检测一个“键”是否在字典中
>>>a = {'name':'daxian','age':18,'job':'teacher'}
>>> 'name' in a
True
45.字典_元素的添加_修改_删除
1.新增“键值对”
如果“键”已经存在,则覆盖旧的键值对;如果“键”不存在,则新增“键值对”。
>>> a = {'name':'daxian','age':18,'job':'teacher'}
>>> a['address'] = '三环内'
>>> a
{'name': 'daxian', 'age': 18, 'job': 'teacher', 'address': '三环内'}
>>> a['age'] = 16
>>> a
{'name': 'daxian', 'age': 16, 'job': 'teacher', 'address': '三环内'}
2.使用 update将新字典中所有键值对全部添加到旧字典对象上。
如果key有重复,则直接覆盖
>>> a = {'name':'daxian','age':18,'job':'teacher'}
>>> b = {'name':'gaoqi','money':'1000','sex':'male'}
>>> a.update(b)
>>> a
{'name': 'gaoqi', 'age': 18, 'job': 'teacher', 'money': '1000', 'sex': 'male'}
3.元素的删除
可以使用del()方法;或者 clear()删除所有键值对;pop()删除指定值对,并返回对应的“值对象"。
>>> a = {'name':'daxian','age':18,'job':'teacher'}
>>> del(a['name'])
>>> a
{'age': 18, 'job': 'teacher'}
>>> a = {'name':'daxian','age':18,'job':'teacher'}
>>> a.pop('age')
18
>>> a.clear()
>>> a
{}
4.popitem():随机删除和返回该键值对。
字典是“无序可变序列”,因此没有第一个元素、最后一个元素的概念; popitem弹出随机的项,因为字典并没有"最后的元素"或者其他有关顺序的概念。若想一个接一个地移除并处理项,这个方法就非常有效(因为不用首先获取键的列表)。
>>> a.popitem()
('job', 'teacher')
>>> a
{'name': 'daxian', 'age': 18}
>>> a.popitem()
('age', 18)
>>> a
{'name': 'daxian'}
46.字典_序列解包用于列表元组字典
序列解包可以用于元组、列表、宇典。作用:序列解包可以让我们方便的对多个变量赋值。
>>> x,y,z = (10,20,30)
>>> x
10
>>> (a,b,c) = (10,20,30)
>>> a
10
>>> [a,b,c] =[10,20,30]
>>> a
10
序列解包用于字典时,默认是对“键”进行操作:如果需要对键值对操作,则需要使用items();如果需要对“值”进行操作,则需要使用 values();
s = {'name':'daxian','age':18,'job':'teacher'}
>>> name,age,job = s #默认对“键”进行操作
>>> name
'name'
>>> name,age,job = s.items() #对“键值对”进行操作
>>> name
('name', 'daxian')
>>> name,age,job = s.values() #对“值”进行操作
>>> name
'daxian'
47.字典_复杂表格数据存储_列表和字典综合嵌套(反复练一练,非常重要)
本质上,所有的数据都是表格
表格数据使用字典和列表存储,并实现访问
#定义行
a = {'name':'阿大','age':18,'salary':30000,'city':'BJ'}
b ={'name':'阿二','age':19,'salary':20000,'city':'SH'}
c ={'name':'阿三','age':20,'salary':10000,'city':'SZ'}
#生成表格
tb = [a,b,c]
#打印第二行人的薪资
print(tb[1].get('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('city'))
48.字典_核心底层原理_内存分析_存储键值对过程(重要)
存
字典对象的核心是散列表。散列表是一个稀疏数组(总是有空白元素的数组),数组的每个单元叫做 bucket。每个 bucket有两部分:一个是键对象的引用,一个是值对象的引用
由于,所有 bucket结构和大小一致,我们可以通过偏移量来读取指定 bucket
将一个键值对放进字典的底层过程
>>> a = {}
>>> a['name'] = 'gaoqi'
假设字典a对象创建完成后,数组长度为8。
我们要把‘name’='gaoqi’这个键值对放到字典对象a中,首先第一步需要计算键‘name’的散列值。Python中可以通过hash()来计算
>>> bin(hash('name'))
'-0b10110010000100001110101110000100010010101110011011110011111111'
由于数组长度为8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即101”,十进制是数字5。我们查看偏移量5,对应的 bucket是否为空。如果为空,则将键值对放进去。如果不为空,则依次取右边3位作为偏移量,即“100",十进制是数字4。再查看偏移量为4的 bucke是否为空。直到找到为空的 bucket将键值对放进去。
流程图如下:
扩容: Python会根据列表的拥挤程度扩容。扩容指的是创造更大的数组,将原有内容拷贝到新数组中。
接近2/3时候,数组就会扩容
49.字典_核心底层原理_内存分析_查找值对象过程
取
我们明白了,一个键对是如何存储到数组中的,根据键对象取到值对象,理解起来就简单了
>>> a= {}
>>> a['name'] = 'daxian'
>>> a.get('name')
'daxian'
当我们调用a.get(“name”),就是根据键"name"查找到“键值对”从而找倒值对象" gaoqi"。
第一步,我们仍然要计算"name”对象的散列值
>>> bin(hash('name'))
'-0b10110010000100001110101110000100010010101110011011110011111111'
和存储的底层流程算法一致,也是依次取散列值的不同位置的数字。
假设数组长度8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即“101”,十进制是数字5,我们查看偏移量5,对应的 bucket是否为空。如果为空,则返回None。如果不为空则将这个 bucket的键对象计算对应散列值,和我们的散列值进行比较。如果相等,则将对应“值对象”返回。如果不相等,则再依次取其他几位数字,重新计算偏移量。依次取完然没有找到。
流程图如下
用法总结
1.键必须可散列
(1)数字、字符串、元组,都是可散列的。
(2)自定义对象需要支持下面三点
①支持hash()函数
②支持通过__eq__()方法检测相等性
③若a==b为真,则hash(a)==hash(b)也为真
2.字典在内存中开销巨大,典型的空间换时间。
3.键查询速度很快
4.往字典里面添加新建可能导致扩容,导致散列表中键的次序变化。因此,不要在遍历字
典的同时进行字典的修改。最好先遍历,把需要改的值取出来,再进行修改。
50.集合_特点_创建和删除_交集并集差集运算
集合是无序可变,元素不能重复。实际上,集合底层是字典实现,集合的所有元素都是字典中的“键对象”,因此是不能重复的且唯一的。
键对象、不可重复、唯一的
集合创建和删除
1.使用{}创建集合对象,并使用add0方法添加元素
>>> a = {3,5,7}
>>> a
{3, 5, 7}
>>> a.add(9)#add()添加元素
>>> a
{9, 3, 5, 7}
>>> a.add(9)
>>> a
{9, 3, 5, 7}#不可重复,唯一的
2.使用set(),将列表、元组等可迭代对象转成集合。如果原来数据存在重复数据,则只保留一个
>>> a =[1,2,3,4,5,1,2,3]
>>> b = set(a)
>>> b
{1, 2, 3, 4, 5}
3.remove()删除指定元素; clear()清空整个集合
>>> a = {1, 2, 3, 4, 5}
>>> a.remove(1)
>>> a
{2, 3, 4, 5}
>>> a.clear()
>>> a
set()
集合相关操作
像数学中概念一样, Python对集合也提供了并集、交集、差集等运算。我们出示例
>>> a = {1,3,'sex'}
>>> b = {'he','it','sex'}
>>> a|b #并集
{1, 'he', 3, 'it', 'sex'}
>>> a&b #交集
{'sex'}
>>> a-b #差集
{1, 3}
>>> a.union(b) #并集
{1, 'he', 3, 'it', 'sex'}
>>> a.intersection(b) #交集
{'sex'}
>>> a.difference(b) #差集
{1, 3}
51.Pycharm开发环境的下载安装配置_项目管理
52.单分支选择结构_条件表达式详解
简介
选择结构通过判断条件是否成立,来决定执行哪个分支。选择结构有多种形式,分为:单分支、双分支、多分支。
单分支选择结构
if语句单分支结构的语法形式如下
if条件表达式
语句/语句块(要有缩进,四个空格)
其中:
①.条件表达式:可以是逻辑表达式、关系表达式、算术表达式等等
②.语句/语句块:可以是一条语句,也可以是多条语句。多条语句,缩进必须对齐一致。
a = input('请输入一个数字')
if int(a) <= 10: #input默认返回值是一个字符串,要把a转化为整形
print(a)
条件表达式详解
在选择和循环结构中,条件表达式的值为 False的情况如下:
False、0、0.0、空值None、空序列对象〔空列表、空元组、空集合、空字典、空字符串)、空 range对象、空迭代对象
其他情况,均为True,这么看来, Python所有的合法表达式都可以看做条件表达式,甚至包括函数调用的表达式
if 3: #整数3作为条件表达式
print('ok')
a = [] #列表作为条件表达式,由于为空列表,是False
if a:
print('空列表,False')
c = 9
if 3 < c < 10:
print('3 < c < 10')
s = 'False' # 非空字符串,是True
if s:
print('非空字符串,是True')
if True:
print('true')
条件表达式中,不能有赋值操作符“=”
在Python中,条件表达式不能出现赋值操作符‘=’,避免了其他语言中经常误将关系运算符“==”写作赋值运算符“=”带来的困扰。如下代码将会报语法错误:
if 3 < c and (c=20):
print('赋值操作符‘=’不能出现在条件表达式中')
53.双分支选择结构_三元运算符的使用详解
双分支结构的语法
格式如下
if条件表达式:
语句1/语句块
else:
语句2/语句块2
num = input("请输入一个数字:\n")
if int(num) < 10:
print(num)
else:
print("这个数字太大了!")
三元条件运算符
Python提供了三元运算符,用来在某些简单双分支赋值情况。三元条件运算符语法格式如下
条件为真时的返回值 if(条件表达式) else条件为假时的值
上一个案例代码,可以用三元条件运算符实现:
num = input("请输入一个数字:\n")
print(int(num) if int(num) < 10 else '这个值太大了')
可以看到,这种写法更加简洁,易读。
54.多分支选择结构
多分支选择结构的语法格式如下:
if条件表达式1:
语句1/语句块1
elif条件表达式2:
语句2/语句块2
…
elif条件表达式n:
语句n/语句块
[else:
语句n+1/语句块n+1
]
【注】
1、多个条件语句之间必须要有逻辑关系,顺序不能随意颠倒
2、计算机行业,描述语法格式时,使用中括号[]通常表示可选,非必选
方法1:使用了完整的条件表达式
每个分支都使用了独立、完整的判断,顺序可随意挪动,而不影响程序运行。
import random #导入随机包
score = random.randint (0,100) #随机生成一个0~100的整数
if score < 60:
grade = "不及格"
if 60 < score < 80:
grade = "及格"
if 80 < score < 90:
grade = "良好"
if score > 90:
grade = "优秀"
print("成绩:{0},等级:{1}".format(score,grade))
方法2:利用多分支结构
多个条件语句之间必须要有逻辑关系,顺序不能随意颠倒
import random #导入随机包
score = random.randint (0,100) #随机生成一个0~100的整数
if score < 60:
grade = "不及格"
elif score < 80: #60-80之间
grade = "及格"
elif score < 90:
grade = "良好"
else:
grade = "优秀"
print("成绩:{0},等级:{1}".format(score,grade))
import random #导入随机包
x = random.randint(-100,100)#随机生成一个0~100的整数
y = random.randint(-100,100)
print("({0},{1})".format(x,y))
if (x == 0 and y == 0):
print("这是原点")
elif (x == 0):
print("该点位于y轴")
elif (y == 0):
print("该点位于x轴")
elif (x > 0 and y > 0):
print("该点位于第一象限")
elif (x < 0 and y > 0):
print("该点位于第二象限")
elif (x < 0 and y < 0):
print("该点位于第三象限")
else:
print("该点位于第四象限")
55.选择结构的嵌套
选择结构可以嵌饔,使用时一定要注意控制好不同级别代码块的缩进量。因为缩进量决定了代码的从属关系。语法格式如下:
if 表达式1:
语句块1
if 表达式2:
语句块2
else:
语句块3
else:
if 表达式4:
语句块4
score = int(input("请输入成绩(0-100):"))
grade = ""
if score > 100 or score < 0:
score = int(input("请再次输入成绩(0-100):"))
if score < 60:
grade = "E"
elif score <70:
grade = "D"
elif score <80:
grade = "C"
elif score <90:
grade = "B"
else:
grade = "A"
print("成绩:{0},等级:{1}".format(score,grade))
也可以用下面代码更少的方法。不过,需要思考为什么这么写
score = int(input("请输入成绩(0-100):"))
degree = 'ABCDE'
num = 0
if score > 100 or score < 0:
score = int(input("请再次输入成绩(0-100):"))
else:
num = score//10
if num < 6: num = 5
degree = degree[9-num]
print("成绩:{0},等级:{1}".format(score,degree))
56.while循环结构_死循环处理
循环结构用来重复执行一条或多条语句。
表达这样的逻辑:如果符合条件,则反复执行循环体里的语句。在每次执行完后都会判断一次条件是否为True,如果为True则重复执行循环体里的语句。
图示如下:
循环体里面的语句至少应该包含改变条件表达式的语句,以使循环趋于结束;否则,就会变成一个死循环。
while循环
while循环的语法格式如下:
While条件表达式
循环体语句
【操作】利用while打印0-10的数字
num = 0
while num <= 10:
print(num,end = '\t')
num += 1
【操作】计算1-100之间的数字的累加和
num = 1
sum_num = 0
while num <= 100:
num += 1
sum_num = sum_num + num
print('1-100所有数的累加和:',sum_num)