本章将继续学习六大数据类型的字典与集合,在此基础上理解嵌套和深浅拷贝。本章中概念较多,诸君请在理解的基础上掌握。

4.1.1什么是字典

字典(dictionary,缩写为dict)是形如{"a":1,"b":2}这样前后被大括号包裹、各个元素之间以英文逗号间隔、元素中间以英文冒号间隔的数据类型,在Python3.5以前字典是无序的,在Python3.6(含)之后,字典是有序的。

字典相较于列表,数据间关联强且查询速度快,与列表一样,字典也可以被打印。

dic={"a":1,"b":2,"c":3}print(dic)#{a:1,b:2,c:3}print(type(dic))#classdict

使用变量来创建字典,创建后变量重新赋值,这不会影响使用变量创建的字典。

num=2s="c"dic={"a":1,"b":num,s:3}#变量指向的值充当字典的键或值num=5s="abc"#字典已创建完毕,变量重新赋值不影响字典print(num,s)#5abcprint(dic)#{a:1,b:2,c:3}

字典的元素中间使用英文冒号间隔,冒号前面的叫做键(key),冒号后面的叫做值(value),所以字典内的元素又叫做键值对(keyvaluepair)。键和值的关系就像钥匙和房间,一把钥匙开一个房间的锁,钥匙只能有这一把,钥匙变型后就打不开房间的锁,具体将在4.1.2详细讲解。

映射是一个很重要的概念,就像水中映月一样,湖水映射天空中的明月。字典中的键值对一一对应,字典是映射类型,此后我们还会遇到映射这个概念。

#键值键值dic={"name":"Nancy","age":18}

对字典来说,非空字典布尔值是True,空字典的布尔值是False。

dic1={}#此处dic是dictionary的缩写dic2={}#无论有无空格,都是空字典dic3=dict()#使用dict()内置函数创建空字典dic4={"a":1}#只有1个元素省略逗号dic5={"a":1,}#只有1个元素加逗号print(type(dic1),bool(dic1),dic1)#classdictFalse{}print(type(dic2),bool(dic2),dic2)#classdictFalse{}print(type(dic3),bool(dic3),dic3)#classdictFalse{}print(type(dic4),bool(dic4),dic4)#classdictTrue{a:1}print(type(dic5),bool(dic5),dic5)#classdictTrue{a:1}

鱼和熊掌不可兼得,字典查询速度快,内存消耗却是巨大的。具体原因形象化解释下,就像我们查找字典上的某个单词,一种方法是逐页翻找单词(不可跳跃),一种方法是按照字母表查找。前者类似于Python列表,列表越大查找越慢,但不需要字母表占用纸张。后者类似于Python字典,不会随着字典的变大而变慢,但字母表需要占用纸张,这里的纸张就相当于内存。

在存储大量数据时,列表以时间换空间,字典以空间换时间。具体说来,在处理大量数据时,列表内存消耗小,但是查询慢,字典内存消耗大,但查询速度快。

需要注意的是,字典不支持切片,强行切片将会引发报错。

dic={"a":1,"b":2,"c":3}dic[0:2]"""TypeError:unhashabletype:slice类型错误:不可哈希类型:切片"""

字典也不支持拼接,强行拼接将会引发报错。

dic={"a":1,"b":2,"c":3}dic+dic"""TypeError:unsupportedoperandtype(s)for+:dictanddict类型错误:+不支持的操作类型:dict和dict"""dic*2"""TypeError:unsupportedoperandtype(s)for*:dictandint类型错误:*不支持的操作类型:dict和int"""

字典也不支持索引操作,但如果强行使用,可能会报错,将在4.1.6中详细讲解。

4.1.2字典的创建

创建字典时键必须是不可变数据类型,不可以是可变数据类型。值可以是任意数据类型,也就是六大数据类型中能够在字典中充当键的只有数字(含布尔值)、字符串、元组这三种。字典中的键唯一不重复,如果有多个重复的键,仅保留最后一个键值对。

dic1={3.14:"OK",True:98}dic2={"Lu":,(1,2):"world"}#键虽然可以是元组,但一般不这么用dic3={[1,2]:0}#TypeError:unhashabletype:listdic4={{1,2}:0}#报错#集合充当键,集合将在4.2中进行讲解dic5={{3.14:"OK"}:0}#报错"""TypeError:unhashabletype:dict类型错误:不可哈希类型:字典"""dic6={"a":1,"a":2}#键重复print(dic6)#{a:2}

字典根据键来计算值的存储位置,这种计算位置的算法称为哈希算法(hash)。每次计算一个键必须得到相同的结果,如果键发生改变,根据键计算的结果就会找不到对应的值,这种混乱是不期望发生的。所以不可变数据类型也叫做可哈希数据类型,可变数据类型也叫做不可哈希数据类型,哈希(hash)将会更高级教程中讲到。

字典的创建总共有六种方式,前三种最为重要,需要重点掌握。

01.dict()

dic1={"a":1,"b":2,"c":3}dic2=dict({"a":1,"b":2,"c":3})print(dic1,type(dic1))#{a:1,b:2,c:3}classdictprint(dic2,type(dic2))#{a:1,b:2,c:3}classdict

02.元组或列表

dic1=dict((("a",1),("b",2),("c",3)))#dict()括号内是(("a",1),("b",2),("c",3))dic2=dict([("a",1),("b",2),("c",3)])#dict()括号内是[("a",1),("b",2),("c",3)]dic3=dict([["a",1],["b",2],["c",3]])#dict()括号内是[["a",1],["b",2],["c",3]]dic4=dict((["a",1],["b",2],["c",3]))#dict()括号内是(["a",1],["b",2],["c",3])print(dic1,type(dic1))#{a:1,b:2,c:3}classdictprint(dic2,type(dic2))#{a:1,b:2,c:3}classdictprint(dic3,type(dic3))#{a:1,b:2,c:3}classdictprint(dic4,type(dic4))#{a:1,b:2,c:3}classdict

03.赋值

dict()括号内填入多个变量赋值,中间以英文逗号间隔,以变量名为字符的字符串充当字典的键,赋给变量的值充当字典的值。这种情况需要特别注意,括号内被赋值的变量名需符合命名规范,通过这种方式创建出的字典,键只能是字符串类型。

dic=dict(a=1,b=2,c=3)print(dic)#{a:1,b:2,c:3}dic=dict("a"=1,"b"=2,"c"=3)#报错#变量名不能是字符串dic=dict(1="a",2="b",3="c")#报错#变量名不能是数字dic=dict(("a","b")=1,("c","d")=2)#报错#变量名不能是元组"""SyntaxError:expssioncannotcontainassignment,perhapsyoumeant"=="?语法错误:表达式不能包含赋值,也许你的意思是“==”?(也许是("a","b")==1这样?)"""dic=dict(a*=1,1b=2,

8=3)#报错#不符合变量名的命名规范"""SyntaxError:invalidsyntax语法错误:无效的语法"""

04.fromkeys()

使用fromkeys()方法将可迭代对象按照顺序依次作为字典的键,然后给每个键一个相同的值,如果没有指定这个相同的值,则值为None这样。from意为“来自”,keys就是“键”的复数形式,fromkeys也就是“键来自......”。

ls=["a","b","c"]dic1=dict.fromkeys(ls,10)print(dic1)#{a:10,b:10,c:10}dic2=dict.fromkeys(ls)print(dic2)#{a:None,b:None,c:None}dic3=dict.fromkeys("abc",10)print(dic3)#{a:10,b:10,c:10}

使用fromkeys()创建字典有个坑,如果创建的字典值为可变数据类型,结果令人捉急。

dic=dict.fromkeys("abc",[1])print(dic)#{a:[1],b:[1],c:[1]}dic["a"].append(98)print(dic)#{a:[1,98],b:[1,98],c:[1,98]}print(id(dic["a"]))#2print(id(dic["b"]))#2print(id(dic["c"]))#2

使用fromkeys()创建字典,如果值为可变数据类型,修改字典的值,其他字典的值也会随之发生改变。分别查看值的内存地址,发现内存地址都是一样的,也就是这些键对应的是同一个值。fromkeys()创建的字典牵一发而动全身,值为可变数据类型时请谨慎使用。

05.zip()函数

zip意为拉链、压缩,zip()括号内填入可迭代对象后,对象中的元素会被一一对应打包成一个个元组,然后返回由这些元组组成的对象,可使用list()将zip对象转换为列表。

ls1=["a","b","c"]ls2=[1,2,3]z1=zip(ls1,ls2)#将两个列表压缩为zip对象z2=zip(ls2,ls1)#注意两列表左右顺序影响结果print(z1)#zipobjectat0xD8DCC0#数字可能不同print(list(z1))#[(a,1),(b,2),(c,3)]print(z2)#zipobjectat0xD8DC52C00#数字可能不同print(list(z2))#[(1,a),(2,b),(3,c)]

如果可迭代对象中元素个数不一致,则返回列表的长度与最短对象相同。

ls1=["a","b","c"]ls2=[1,2,3,4,5]print(list(zip(ls1,ls2)))#[(a,1),(b,2),(c,3)]

可使用zip(*)将列表内的多个元组解压。

ls1=["a","b","c"]ls2=[1,2,3]ls_


本文编辑:佚名
转载请注明出处:网站地址  http://www.cqwpz.com/kcyzl/11336328.html

  • 上一篇文章:
  • 下一篇文章: 没有了
  • 当前时间: