字典
列表中我们通过“下标数字”找到对应的对象。字典中通过“键对象”找到对应的“值对象”。“键”是任意的不可变数据,比如:整数、浮点数、字符串、元组。但是:列表、字典、集合这些可变对象,不能作为“键”。并且“键”不可重复。
“值”可以是任意的数据,并且可重复。
一个典型的字典的定义方式:
a={'name':'gaoqi','age':'18','job':'programmer'}
字典的创建
1.可以使用{}、dic()来创建字典对象
>>>a={'name':'gaoqi','age':18,'job':'programmer'}
>>>b=dict(name='gaoqi',age=18.job='programmer'}
>>>a=dict([("name","gaoqi"),"age",18)])
>>>c=0#空的字典对象
>>>d=dict() #空的字典对象
2.通过zip()创建字典对象
>>>k=['name','age','job']
>>>v=[gaoqi,18,techer]
>>>d=dict(zip(k,v))
>>>d
('name':'gaoqi','age':18,'job':'techer')
3. 通过fromkeys创建值为空的字典
>>>a=dict.fromkeys(['name','age','job'])
>>>a
('name':None,'age':None,'job':None)
字典元素的访问
为了测试各种访问方法,我们这里设定一个字典对象
1.通过[键]获得“值”。若键不存在,则抛出异常。
>>>a={'name':'gaoqi','age':18,job:'programmer'}
>>>a[name]
'gaoqi'
>>>a[age]
18
>>>a['sex']
Traceback(most recent call last):File<pyshell#374>",line 1,in <module>
a['sex]
KeyError:'sex'
2.通过get()方法获得“值”。推荐使用。优点是:指定键不存在,返回None;也可以设定指定键不存在时默认返回的对象。推荐使用get()获取“值对象”。
>>>a.get(name)
'gaoqi'
>>>a.get('sex)
>>>a.get(sex','一个男人')
'一个男人'
3.列出所有的键值对
>>>a.item
dict items(([('name','gaoqi'),('age',18),('job','programmer'])
4.列出所有的键,列出所有的值
>>>a.keys()
dict keys(['name','age','job'])
>>>a.values()
dict values(['gaoqi',18,'programmer'])
5.len()键值对的个数
6.检测一个“键”是否在字典中
>>>a={"name":"gaoqi","age":18}
>>>"name" in a
True
字典元素添加、修改、删除
- 给字典新增“键值对”,如果“键”已经存在,则覆盖旧的键值对,如果“键”不存在,则新增“键值对”。
2.使用update()将新字典中所有键值对全部添加到旧字典对象上。如果key有重复,则直接覆盖。
3.字典中元素的删除,可以使用del()方法;咸者clear()删除所有键值对;pop()删除指定键值对,并返回对应的“值对象”;
3.popitem():随即删除和返回该键值对。字典是“无序可变序列”,没有第一个和最后一个的差别。随机删除和返回该键值对。字典是“无序可变序列”,因此没有第一个元素、最后一个元素的概念;popitem弹出随机的项,因为字典并没有“最后的元素“或者其他有关顺序的概念。若想一个接一个地移除并处理项,这个方法就非常有效(因为不用首先获取键的列表)。
序列解包
序列解包可以用于元组、列表、字典,可以方便对多个变量赋值。
序列解包用于字典时,默认是对“键”进行操作;如果需要对键值对操作,则需要使用item();如果需要对“值”进行操作,则需要使用value()。
- 表格数据使用字典和列表存储,并实现访问
所有数据本质都是表格
字典核心底层原理(重要,建议多加练习)
r1=("name":"高小一","age"=18,"salary":30000,"city"="beijing")
r2=("name":"高小二","age"=18,"salary":30000,"city"="beijing")
r3=("name":"高小三","age"=18,"salary":30000,"city"="beijing")
tb=[r1,r2,r3]
#获得第二行的人的薪资
print(tb(1),get("salary"))
#打印表中所有的薪资
for i in range(len(tb)): #-->0,1,2
print(tb[i],get("salary"))
#打印表的所有数据
for i in range(len(tb))
print(tb[i].get("name").tb[i].get("salary").tb[i].get("city"))
所有的数据都可以生成表格的形式
字典核心底层原理(重要)
字典对象的核心是散列表,散列表是一个稀疏数组(总是有空白元素的数组),数组的每个单元叫做bucket。每个bucket由两部分,一个是键对象的引用,一个是值对象的引用。
由于,每个bucket(桶,表元)有两部分:一个是键对象的引用,一个是值对象的引用。
key可以是数字,可以是字符串。
由于所有bucket结构和大小一致,我们可以通过偏移量来读取指定bucket。
将一个键值对放到字典的底层过程
假设字典a对象创建完后,数组长度为8.
我们要把“name”=“gaoqi”这个键值对放到字典对象a中,首先第一步要计算
如果字典2/3满了,字典会自动扩容
我们要把"name”="gaoqi”这个键值对放到字典对象a中,首先第一步需套计算键”name”的散列值。Python中可以通过hash()来计算。
3
>>>bin(hash("name"))
-0b1010111101001110110101100100101
由于数组长度为8,我们可以拿计算出的散列值的最右边3位数字作为偏移量,即“101",十进制是数字5。我们查看偏移量5,对应的bucket是否为空。如果为空,则将键值对放进去。如果不为空,则依次取右边3位作为偏移量,即“100”,十进制是数字
4.再查看偏移量为4的bucket是否为空。直到找到为空的bucket将键值对放进去。
根据键查找“键值对”
用法总结:
1.键必须可散列
(1)数字、字符串、元组,都是可散列的。
(2)自定义对象需要支持下面三点:
①支持hash0函数
②支持通过_eq__0方法检测相等性。
③若a==b为真,则hash(a)==hash(b)也为真。
2.字典在内存中开销巨大,典型的空间换时间。
3.键查询速度很快
4.往字典里面添加新建可能导致扩容,导致散列表中键的次序变化。因此,不要在遍历字典的同时进行字典的修改。
集合
集合是无序可变,元素不能重复(集合不能容纳重复元素)。实际上,集合底层是字典实现,里面是键对象。因此是不能重复且唯一的。
集合创建和删除
1. 使用{}创建集合对象,使用add()增加对象
2. 使用set(),将列表、元组等可迭代对象转成集合。如果原来数据存在重复数据,则只保留一个。
3.使用remove()删除指定元素
集合的相关操作
并集 a|b, a.union(b)
交集 a&b, a.intersection(b)
差集 a-b, a.difference(b)
分支结构
选择结构通过判断条件是否成立,来决定执行哪个分支。选择结构有多种形式,分为:单分支、双分支、多分支。流程图如下:
条件表达式详解
在选择和循环结构中,条件表达式的值为False的情况如下:
False、0、0.0、空值None、空序列对象(空列表、空元祖、空集合、空字典、空字符串)、空range对象、空迭代对象。
其他情况,均为True。这么看来,Python所有的合法表达式都可以看做条件表达式,甚至包括函数调用的表达式。
条件表达式中,不能有赋值操作符“="
在Python中,条件表达式不能出现赋值操作符“=”,避免了其他语言中经常误将关系运算符“==”写作赋值运算符“=”带来的困扰。如下代码将会报语法错误:
if 3<c and(c=20):print(“赋值符不能出现在条件表达式中")
双分支选择结构
双分支结构的语法格式如下:
if 条件表达式:
语句1/语句块1
else:
语句2/语句块2
三元条件运算符
多分支选择结构
多分枝选择结构语法格式如下:
if 条件表达式1:
语句/语句块1
elif条件表达式2
语句2/语句块2
elif条件表达式n:
语句n/语句块n
[else:
语句n+1/语句块n+1
]
选择结构嵌套
注意控制不同代码级别的缩进量
>>>if 表达式1:
>>> 语句块1
>>> if 表达式2:
>>> 语句块2
>>> else
>>> 语句块3
>>>else
>>> if 表达式4:
>>> 语句块4
循环结构
while循环
while循环的语法格式如下:
while条件表达式:
循环体语句
>>>num = 0
>>>while num<=10
>>> print(num)
>>> num += 1
For循环和可迭代对象遍历
for循环常用于可迭代对象的遍历,for循环的语法格式如下:
for 变量 in 可迭代对象
循环体语句
操作:遍历一个元组或列表
for x in (20,30,40)
Print(x*3)
range对象
range对是一种迭代器对象,用来产生指定范围的数字序列,格式为:
Range(start,end [,step)
嵌套循环/多重循环
一个循环体内可以嵌入另一个循环
Break语句
用来结束整个循环,跳出嵌套循环最近一层的循环
>>>while True
>>> a=input(“请输入Q或q结束”)
>>> if a.upper()==”Q”:
>>> print(“循环结束,退出”)
>>> break
>>> else:
>>> print(a)
Continue语句
结束本次循环,继续下一次
Else语句
循环代码优化
- 减少循环内部不必要的计算
- 减少内层循环不必要的计算
- 局部变量查询较快,尽量使用局部变量
列表进行元素插入和删除,尽量在列表尾部
字符串连接用join不用+