一、字典(dict)数据类型讲解
1. 字典的定义
python的字典(dict)属于映射类型)是存储键值对(key-value)数据的容器,是数据的无序集合。字典内的元素都是key:value形式的键值对,所有键值对存储在一对大花括号{}中,每一个键值对之间用逗号分隔,键必须是唯一的,但值则不必,值可以重复出现。
{'name': '小明', 'age': 14}
#该字典的两个key('name'和'age'都是字符串类型,所以用引号包括,实际上,key和value都可以不是字符串,可以是数值等:
{1:100,2:200}
字典这种数据类型本质上是一种映射关系的容器,其内部使用散列表(hash)实现。尽管python官方定义的名称叫字典(dict),但我们有时候也会用其他名称来代指字典(在不同的编程语言中有不同的名称),比如关联数组(Associative array)、散列表(Hash)、地图(Map)等,无论是什么称呼,你要清楚,他们指的都是字典这种数据类型,存储的是键值对。
字典中的key不可重复
字典的key不允许重复,或者说重复了会被后面的覆盖。如果向字典中插入重复的key,新的value会替换旧的value。当数值类型做为字典的key时,遵循数字比较的一般规则,如果数值相等则视为同一个key,例如1 和 1.0 ,他们使用比较运算符 == 进行比较时是相等的,但考虑到计算机对浮点型数据存储的是近似值,因此用float类型数据做字典的key是不明智的。此外,尽量避免使用bool类型对象做字典的key,bool类型是int类型的子类,True与1在python中是相等的,因此下面的字典看似定义了两个key:value对,实际只有一个。
int_dict = {
1: '1做key',
True: 'True做key'
}
print(int_dict) # 结果是{1: 'True做key'},后定义的True: 'True做key' 覆盖了之前定义的1: '1做key'。
#一般来说,为了字典内容看起来更直观,我们都会把左右花括号单独放在一行,内容分布在中间,更直观,而且不会影响结果。
字典中的key需要是不可变类型
在python中,任意类型的对象都可以做字典的value,但只有可散列的对象才能做字典的key,散列就是hash,可散列就是hashable,简单说就是字典的key必须为不可变类型。像列表,字典本身,集合都不是可hash的对象(不能hash说明是可变的数据类型),因此他们不能做字典的key。
判断是一个对象是否可hash,可以使用内置函数hash(),如果对象是可hash的,hash函数就能够返回对象的hash值,若不可hash则会抛出TypeError异常。当然一般来说,我们不用去判断,因为我们用到的能做key的数据类型基本明确:字符串、数值、元组都可以作为dict的key,后面学到的类的对象实例也可以,因为自定义类的对象默认是不可变的。
# 字符串作为key
>>> D = {"aa":"aa","bb":"bb"}
>>> D
{'aa': 'aa', 'bb': 'bb'}
# 数值作为key
>>> D = {1:"aa","bb":"bb"}
>>> D[1]
'aa'
# 元组作为key
>>> D = {(1,2):"aa","bb":"bb"}
>>> D
{(1, 2): 'aa', 'bb': 'bb'}
# 列表作为key,报错
>>> D = {[1,2]:"aa","bb":"bb"}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
2. 创建python字典
2.1 使用{}创建字典
**注意:**dict作为 Python 的关键字和内置函数,变量名不建议命名为 dict。
使用一对大括号{} ,可以创建一个空字典,字典里没有任何元素。
empty_dict = {}
在{}里添加key:value对,可以创建非空的字典,每一个元素(键值对)之间用逗号分隔。
contacts_dict = {
"小王": '15666666666',
"小张": '15777777777',
"小李": '15888888888'
}
#字典中元素的个数是3,一个key:value对算是一项元素,这个字典里的key和value都是字符串类型
2.2 使用内置函数dict创建字典
dict函数返回一个新的字典,语法如下,说明使用dict()函数创建字典的方式又能分成三种:
class dict(**kwarg)
class dict(mapping, **kwarg)
class dict(iterable, **kwarg)
参数说明:
- kwarg 关键字参数
- mapping 关联式的容器类型
- iterable 可迭代对象
1.传入关键字参数的方式创建字典 dict(key=value)
>>> new_dict = dict(name='小明', age=14)
>>> new_dict
{'name': '小明', 'age': 14}
2.传入一个字典的方式创建字典 dict({})
>>> new_dict = dict({'name': '小明', 'age': 14})
>>> new_dict
{'name': '小明', 'age': 14}
**3.传入可迭代对象的方式创建字典 dict(iterable) **
>>> new_dict = dict([('name', '小明'), ('age', 14)]) #列表是一种可迭代对象
>>> new_dict
{'name': '小明', 'age': 14}
#其中iterable的每个元素必须是两元素的数据对象,例如("one",1)、["two",2]
-
注意:后两种都可以结合第一种方式创建字典 (但我测试会报错)
2.3 使用dict对象的方法创建字典
1.使用dict对象的fromkey()方法
fromkey(seq,value)
是dict的类方法,所以可直接通过dict类名来调用(当然,使用已存在的对象来调用也没有问题)。它构造的字典的key来自于给定的序列,值来自于指定的第二个参数,如果没有第二个参数,则所有key的值默认为None。所以,第二个参数是构造新dict时的默认值。
例如,构造一个5元素,key全为数值的字典:
>>> dict.fromkeys(range(5))
{0: None, 1: None, 2: None, 3: None, 4: None}
>>> dict.fromkeys(range(5), "aa")
{0: 'aa', 1: 'aa', 2: 'aa', 3: 'aa', 4: 'aa'}
再例如,根据已有的dict来初始化一个新的dict:
>>> d = dict(one=1, two=2, three=3, four=4, five=5)
>>> dict.fromkeys(d)
{'one': None, 'two': None, 'three': None, 'four': None, 'five': None}
>>> dict.fromkeys(d, "aa")
{'one': 'aa', 'two': 'aa', 'three': 'aa', 'four': 'aa', 'five': 'aa'}
因为key的来源可以是任意序列,所以也可以从元组、列表、字符串中获取。
>>> dict.fromkeys("abcd","aa")
{'a': 'aa', 'b': 'aa', 'c': 'aa', 'd': 'aa'}
>>> L = ["a", "b", "c", "d"]
>>> dict.fromkeys(L)
{'a': None, 'b': None, 'c': None, 'd': None}
>>> T = ("a", "b", "c", "d")
>>> dict.fromkeys(L)
{'a': None, 'b': None, 'c': None, 'd': None}
2.使用dict对象的copy()方法
dict的copy()方法会根据已有字典完全拷贝成一个新的字典副本。但需要注意的是,拷贝过程是浅拷贝。
>>> d = {'one': 1, 'two': 2, 'three': 3, 'four': 4}
>>> dd = d.copy()
>>> dd
{'three': 3, 'one': 1, 'two': 2, 'four': 4}
>>> id(d["one"]), id(dd["one"])
(10919424, 10919424)
2.4 使用字典推导式创建字典
后文再解释
3. 增改:字典新增或修改其内元素
3.1字典的索引方式
通过对字典的一个key进行赋值可以向字典中插入新的key:value对,字典在使用key时,必须要用中括号[]紧跟在字典后面,在中括号里填写key的值,这种方式被称为索引方式。如果你要赋值的key是字典中已有的,那么赋值后,字典不会新增一个同样的key,而是将已有的key:value更新。
score_dict = {'小明': 96}
score_dict['小刚'] = 100
print(score_dict) #结果是{'小明':96,'小刚':100}
score_dict['小名'] = 200
print(score_dict) #结果是{'小明':200,'小刚':100}
3.2字典的update()方法
python字典的update方法可以根据一个新的字典来更新原有的字典。新字典的key如果不在原字典中,update方法会插入新的key与value;如果新字典的key也在原字典中,update方法会根据新字典的key所对应的value更新原字典。
dict.update(dict2)
参数
- dict2 用于更新原字典的新字典
返回值
update方法没有返回值,它原地更新字典
示例代码
一般的使用模式是dic1.update(dic2),将dic2的内容更新到dic1中,如果一个key,在两个字典中都存在,则value的最终结果取决于dic2
score_dict = {
'小明': 96,
'小刚': 98,
'小红': 94
}
score_dict2 = {
'小明': 100,
'小丽': 98,
}
score_dict.update(score_dict2)
print(score_dict)
#结果是 {'小明': 100, '小刚': 98, '小红': 94, '小丽': 98}
3.2字典的setdefault()方法
python字典的setdefault方法为指定的key设置对应的value值,如果key已经存在,那么不做任何操作,setdefault方法只有在key不存在时才会起作用
dict.setdefault(key, default=None)
参数
- key 想要设置的key
- default 当key不存在时,设置的默认值
返回值
setdefault方法没有返回值,它只是原地修改字典
示例代码
这个方法和get有些类似,如果key不存在,则增加新的键值对,如果key已经存在,则不做任何操作
score_dict = {
'小明': 96,
'小刚': 98,
'小红': 94
}
score_dict.setdefault('小明', 100) # 小明这个key已经存在,因此这行语句不产生任何影响
score_dict.setdefault('小丽', 97) # 小丽这个key不存在,增加新的键值对,key为小丽,value为97
print(score_dict)
#结果是 {'小明': 96, '小刚': 98, '小红': 94, '小丽': 97}
示例:一个列表里存放了若干个单词,现在要求你统计每个单词出现的次数,并将单词与单词出现的次数存储到字典中。
你可以这样实现代码
lst = ['green', 'white', 'black', 'white', 'green', 'green']
info = {}
for word in lst:
if word not in info:
info[word] = 0
info[word] += 1
print(info)
上面的代码虽然完成了要求,但是不够优雅,不符合python一贯的简洁作风,你应该使用setdefault方法让代码看起来更加简洁
lst = ['green', 'white', 'black', 'white', 'green', 'green']
info = {}
for word in lst:
info.setdefault(word, 0)
info[word] += 1
print(info)
setdefault方法尝试为key设置默认值,如果这个key已经存在,那么setdefault什么都不做,如果key不存在,则向字典里新增一个key-value键值对,value就是方法里的第二个参数。
上面的代码里,如果单词不存在于字典中,则设置这个单词所对应的value为0,info[word] += 1 等价于 info[word] = info[word] + 1 ,实现了单词出现次数加1的目的
3.3字典的fromkeys()方法
前面已经介绍过用fromkeys()方法来创建字典,这里再详细一些。
python字典的fromkeys方法以序列 seq 中元素做字典的键,value 为字典所有键对应的初始值创建一个新的字典,value默认值是None
dict.fromkeys(seq[, value])
参数
-
seq 生成新字典的键值序列
-
value 可选参数,新字典所有键值对中value的初始值,默认为None
返回值
fromkeys返回一个新的字典
示例代码
stu_dict = dict.fromkeys(['小明', '小刚'], 90)
print(stu_dict)
程序输出结果为
{'小明': 90, '小刚': 90}
fromkeys方法接受两个参数,第一个参数是序列,可以是列表,也可以是元组,方法将以这个序列里的元素做key,生成新的字典。value由第二个参数来决定,我在代码里传入参数90,所有key所对应的value就都是90,如果不传这个参数,默认value为None
5. 删:字典删除其内元素
5.1使用 del 关键字
删除字典里的某个key:value,可以使用del关键字。
score_dict = {
'小明': 96,
'小刚': 98,
'小红': 94
}
del score_dict['小明']
print(score_dict) # {'小刚': 98, '小红': 94}
5.2字典的pop()方法
pop(key[,default])
- key - 要删除的键
- default - 当键 key 不存在时返回的值
返回值
返回被删除的值:
- 如果
key
存在 - 删除字典中对应的元素 - 如果
key
不存在 - 返回设置指定的默认值 default - 如果
key
不存在且默认值 default 没有指定 - 触发KeyError
异常
score_dict = {
'小明': 96,
'小刚': 98,
'小红': 94
}
score_dict.pop('小明')
print(score_dict) # {'小刚': 98, '小红': 94}
不论是使用del 还是使用pop方法删除字典里的键值对,如果key不存在都会引发KeyError异常,pop与del的不同之处在于,pop会返回所删除键值对的value
score_dict = {
'小明': 96,
'小刚': 98,
'小红': 94
}
del score_dict['小红']
print(score_dict.pop('小明'))
print(score_dict)
程序输出结果
96
{'小刚': 98}
不论是del还是pop方法,都需要指明要删除哪个key,如果想要删除全部的元素,则可以使用clear方法
5.3字典的clear()方法
score_dict = {
'小明': 96,
'小刚': 98,
'小红': 94
}
score_dict.clear()
print(score_dict) # {}
执行clear方法后,score_dict变为一个空字典。clear会清空字典里所有的元素,该方法不需要传入参数,也没有返回值,在python中,函数或方法没有返回值即意味着返回None。
使用clear方法后,字典dic变成了空字典,有人可能会问,这种清空字典的方法和直接将空字典赋值给变量dic有什么区别
dic = {
'小明': 98
}
dic = {}
print(dic)
程序最终输出的结果同样是{},dic 变成了空字典。两种方式,变量dic都变成了空字典,但意义不同,使用clear方法,字典在内存中的地址没有发生变化,但是第二种方法,变量dic指向了一个新的空字典,原来的字典被垃圾回收机制回收了,我们可以通过输出变量的内存地址来验证
dic1 = {
'小明': 98
}
print("使用clear方法前,dic1内存地址为", id(dic1))
dic1.clear()
print(dic1)
print("使用clear方法后,dic1内存地址为", id(dic1))
print("\n\n分割线"+"*"*30 + "\n"*2)
dic2 = {
'小明': 98
}
print("赋值空字典之前,dic1内存地址为", id(dic2))
dic2 = {}
print(dic2)
print("赋值空字典之后,dic1内存地址为", id(dic2))
程序输出结果为
使用clear方法前,dic1内存地址为 4352796640
{}
使用clear方法后,dic1内存地址为 4352796640
分割线******************************
赋值空字典之前,dic1内存地址为 4729716312
{}
赋值空字典之后,dic1内存地址为 4729716168
clear是清空字典,而将一个空字典赋值给变量,并不是清空,只是修改了变量的引用而已。
5.4字典的popitem()方法
popitem() 方法功能描述
随机返回并删除字典中的最后一对键和值。如果字典已经为空,却调用了此方法,就报出 KeyError 异常。
popitem()
返回值
返回最后插入键值对(key, value 形式),按照 LIFO(Last In First Out 后进先出法) 顺序规则,即最末尾的键值对。
**注意:**在 Python3.7 之前,popitem() 方法删除并返回任意插入字典的键值对。
site= {'name': '菜鸟教程', 'alexa': 10000, 'url': 'www.runoob.com'}
# ('url': 'www.runoob.com') 最后插入会被删除
result = site.popitem()
print('返回值 = ', result)
print('site = ', site)
# 插入新元素
site['nickname'] = 'Runoob'
print('site = ', site)
# 现在 ('nickname', 'Runoob') 是最后插入的元素
result = site.popitem()
print('返回值 = ', result)
print('site = ', site)
返回值 = ('url', 'www.runoob.com')
site = {'name': '菜鸟教程', 'alexa': 10000}
site = {'name': '菜鸟教程', 'alexa': 10000, 'nickname': 'Runoob'}
返回值 = ('nickname', 'Runoob')
site = {'name': '菜鸟教程', 'alexa': 10000}
6. 查:字典获取其内元素
字典的索引方式
dict对象中存储的元素没有位置顺序,所以dict不是序列,不能通过下标索引的方式取元素。dict是按照key进行存储的,所以需要通过key作为定位元素的依据,比如取元素或修改key对应的value。
score_dict = {
'小明': 99,
'小刚': 98,
'小红': 94
}
print(score_dict['小红']) # 94
需要特别指出的是,通过key获取value时,如果key不存在,会引发KeyError异常
print(score_dict['小丽'])
字典中并没有'小丽'这个key,因此这样代码会引发异常
Traceback (most recent call last):
File "/Users/kwsy/PycharmProjects/pythonclass/mytest/demo.py", line 7, in <module>
print(score_dict['小丽'])
KeyError: '小丽'
KeyError表示不存在'小丽'这个key。
当然了,你可以使用字典的get()方法,指定一个默认值,防止出现KeyError
get方法功能作用
python字典的get方法返回字典中指定键的值,如果键在字典中不存在,get方法返回默认值value,get方法是一种非常安全的从字典中获取value的方法,键不存在时get方法不会引发异常
dict.get(key[, value])
- key 字典中你想要查找的键
- value 可选参数,通过value可以设置一个默认值的,当key不存在于字典中时,get方法返回value, value默认值是None
返回值
get方法返回key在字典中所对应的value,如果key不存在,则返回可选参数value设置的默认值。
empty_dict = {}
print(empty_dict.get('python'))
print(empty_dict.get('python', 100))
程序输出结果
None
100
keys方法功能作用
python字典的keys方法以可迭代对象的方式返回字典所有的key,keys方法通常用于for循环语句,用于遍历字典的key,可以用list方法将keys方法的返回值转换为列表。
dict.keys()
keys方法无参数
返回值
以可迭代对象的方式返回字典所有的key
示例代码
score_dict = {
'小明': 96,
'小刚': 98,
'小红': 94
}
keys = score_dict.keys()
print(keys, type(keys))
for key in keys:
print(key)
程序输出结果
dict_keys(['小明', '小刚', '小红']) <class 'dict_keys'>
小明
小刚
小红
keys()方法在py2.7里,返回的是包含了所有key的列表,但在py3.6中,返回的是可迭代对象,遍历这个对象,就可以得到字典所有的key
values方法功能作用
python字典的values方法以可迭代对象的方式返回字典中所有的value,values方法通常用于for循环语句,用于遍历字典中的所有value,可以用list方法将values的返回值转换为列表
dict.values()
values方法没有参数
返回值
以可迭代对象的方式返回字典里的所有value
示例代码
score_dict = {
'小明': 96,
'小刚': 98,
'小红': 94
}
values = score_dict.values()
print(values, type(values))
for value in values:
print(value)
values()方法返回的是一个可迭代对象,遍历这个可迭代对象,可以获得字典所有的value
items方法功能作用
python字典的items方法返回一个可迭代对象,类型是dict_items,通常用于for循环语句,以元组的形式对字典中的元素进行遍历。
dict.items()
items方法不需要参数
返回值
返回一个可迭代对象,类型是dict_items
示例代码
items()方法通常被用在字典遍历的场景下
score_dict = {
'小明': 96,
'小刚': 98,
'小红': 94
}
for key, value in score_dict.items():
print(key, value)
items()方法返回一个可迭代对象,使用for循环遍历这个可迭代对象时,得到的是一个元组,元组内包含key和 value
下面的代码向你揭示items()方法返回的对象的本质面目
from collections import Iterable
score_dict = {
'小明': 96,
'小刚': 98,
'小红': 94
}
iter_obj = score_dict.items()
print(isinstance(iter_obj, Iterable))
for item in iter_obj:
print(item)
程序输出结果为
True
('小明', 96)
('小刚', 98)
('小红', 94)
dict.keys()、dict.values 和dict.items返回的都是视图对象,提供了字典实体的动态视图,这就意味着字典改变,视图也会跟着变化。视图对象不是列表,不支持索引,可以使用 list() 来转换为列表。我们不能对视图对象进行任何的修改,因为字典的视图对象都是只读的。
**注意:**Python2.x 是直接返回列表
通过 values 取到 key 的方法:
>>> dic={"a":1,"b":2,"c":3}
>>> list(dic.keys())[list(dic.values()).index(1)]
'a'
当然 你直接写 dic.keys()[1] 也可以得到'a',上面写的这么麻烦,是为了你练习
7.字典的复制
copy方法功能描述
python字典的copy方法返回字典的浅拷贝,copy方法会返回一个新的字典,新的字典在内容上与原字典一模一样。
dict.copy()
参数
copy方法不需要参数
返回值
返回原字典的浅拷贝
示例代码
dic1 = {
'小明': 98
}
dic2 = dic1.copy()
print(dic1)
print(dic2)
程序输出结果为
{'小明': 98}
{'小明': 98}
dic2是dic1的复制品,他们的内容一模一样,在python中,还有一个模块,可以实现数据的复制功能,它就是copy模块
import copy
dic1 = {
'小明': 98
}
dic2 = copy.copy(dic1)
print(dic1)
print(dic2)
这两段代码都实现了浅复制,浅复制是一种危险的复制,建议你不要使用,因为这种复制并没有创建新的对象,因此,你对dic2的修改会影响到dic1
dic1 = {
'stu': ['小明', '小红']
}
dic2 = dic1.copy()
dic2['stu'].append('小刚')
print(dic1)
程序输出结果为
{'stu': ['小明', '小红', '小刚']}
关于对象的深拷贝和浅拷贝,会有专门的章节进行讲解
8 遍历字典
因为元素存储到dict的时候,都经过hash()计算,且存储的实际上是key对应的hash值,所以dict中各个元素是无序的,或者说无法保证顺序。所以,遍历dict得到的元素结果也是无序的。
# python 3.5.2
>>> d = {'one': 1, 'two': 2, 'three': 3, 'four': 4}
>>> d
{'four': 4, 'two': 2, 'three': 3, 'one': 1}
但是在python 3.7中,已经保证了python dict中元素的顺序和插入顺序是一致的。
Changed in version 3.7: Dictionary order is guaranteed to be insertion order. This behavior was an implementation detail of CPython from 3.6.
# python 3.7.1
>>> d = {'one': 1, 'two': 2, 'three': 3, 'four': 4}
>>> d
{'one': 1, 'two': 2, 'three': 3, 'four': 4}
虽保证了顺序,但后面介绍dict的时候,仍然将它当作无序来解释。
遍历字典的key与value是常见的操作,写法很多,下面两种写法都能够实现对字典的遍历。
score_dict = {
'小明': 96,
'小刚': 98,
'小红': 94
}
for i in score_dict:
print(i, score_dict[i])
#当只有一个变量时,遍历字典,得到的结果是key,不要认为是value
这种for循环写法会遍历字典的key,通过key获得所对应的value,另外一种写法是通过字典的items方法来同时遍历字典的key与value
score_dict = {
'小明': 96,
'小刚': 98,
'小红': 94
}
for key, value in score_dict.items():
print(key, value)
两种写法最终输出的结果一致
小明 96
小刚 98
小红 94
常用操作
dic = {"a": 1, "b": 2, "c": 3}
print(dic) # {'a': 1, 'b': 2, 'c': 3}
# print(dic.item) #直接报错 无法继续运行,items(有s)是字典对象的方法,后面需要加括号 items()
print(dic.items) # <built-in method items of dict object at 0x000002D9302BB100>
print(dic.items()) # dict_items([('a', 1), ('b', 2), ('c', 3)])
print(list(dic.items()) # [('a', 1), ('b', 2), ('c', 3)]
print(dic.keys) # <built-in method keys of dict object at 0x0000015275432980>
print(dic.keys()) # dict_keys(['a', 'b', 'c'])
print(list(dic.keys())) # ['a', 'b', 'c']
print(dic.values) # <built-in method values of dict object at 0x0000015275432980>
print(dic.values()) # dict_values([1, 2, 3])
print(list(dic.values())) # [1, 2, 3]
for i,j in dic:
print(i,end="") #会报错not enough values to unpack (expected 2, got 1)
print(i,j,end="")#同样会报错,即便改成 print(i j,end="")也会报错
for i,j in dic.items():
print(i,end="")#结果是连在一起的 abc 因为end参数控制,所以没有分行
print(i,j,end="")#结果是a 1b 2c 3,记得把上一行注释掉,不要运行上一行,否则结果是 aa 1bb 2cc 3
print(i,":",end=" ") #冒号左右没有空格
print(j,end="\n")
# 上面两行print联用,输出结果如下,输出的冒号左右是有空格的,原因是 print(里面的逗号会输出为空格)
# a : 1
# b : 2
# c : 3
for i,j in dic.items():
print(f'{i}:{j}')
# 结果如下,冒号前后没有空格:
# a:1
# b:2
# c:3
for i in dic.items():
print(i)
#结果是
# ('a', 1)
# ('b', 2)
# ('c', 3)
dic = {"a": 1, "b": 2, "c": 3}
for i in dic.items():
print(i[0],end="")
print(i[1],end="")
结果是a1b2c3
dic = {"a": 1, "b": 2, "c": 3}
print(f'{k}:{v}' for k,v in dic.items()) #<generator object <genexpr> at 0x00000259DC4ECF90>
print([f'{k}:{v}' for k,v in dic.items()]) #['a:1', 'b:2', 'c:3']
print("\n".join([f'{k}:{v}' for k,v in dic.items()]))
# 结果是:
# a:1
# b:2
# c:3
dic = {1: ["a"], 2: ["b"]}
dic[2].append("c")
print(dic)
当字典的value值为列表的时候,可以对其使用append等列表专用的方法
dic = {1: ["a"], 2: ["b"]}
if dic[1] in dic:
print("True")
以上写方法是错误的,要说某个 key在不在字典里,要直接用 if key in dic 不要用dic[key]
字典可以为空,但若不为空,键key是必须要有的,而且只能是不可变类型的数字或者字符等,不能是可变的列表,key的值可以没有,如果有的话,可以是数字字符也可以是列表等。
dic = {1: "a", 2: "b"}
if "a" in dic:
print(1)
else:
print(2)
结果会返回2 因为 xx in dic 的时候,xx检查的是字典的key 不会检查value
dic = {1: ["a"], 2: "b"}
if ["a"] in dic:
print(1)
else:
print(2)
结果会报错,因为 ["a"]是列表,而列表不能作为key, xx in dic的时候 ,检查的是字典的key
9.字典的比较
获取字典中最大的值及其键:
prices = {
'A':123,
'B':450.1,
'C':12,
'E':444,
}
max_prices = max(zip(prices.values(), prices.keys()))
print(max_prices) # (450.1, 'B')
10.字典的推导式
字典推导式:
格式:
{key:value for variable in iterable [if expression]}
执行步骤:
- 1、for 循环:遍历可迭代对象,将其值赋给变量。
- 2、if 语句:筛选满足 if 条件的结果。
- 3、存储结构:以键值对的方式存储在字典中。
{x: x**2 for x in (2, 4, 6)} 结果是{2: 4, 4: 16, 6: 36}
字典可以通过以下方法调换 key和 value,当然要注意原始 value 的类型,必须是不可变类型:
dic = {
'a': 1,
'b': 2,
'c': 3,
}
reverse = {v: k for k, v in dic.items()}
print(dic)
print(reverse)
输出如下:
{'a': 1, 'b': 2, 'c': 3}
{1: 'a', 2: 'b', 3: 'c'}
11.字典的计算符
Python 字典 in 操作符用于判断键是否存在于字典中,如果键在字典 dict 里返回 true,否则返回 false。key in dict 如果键在里面 则为True
而 not in 操作符刚好相反,如果键在字典 dict 里返回 false,否则返回 true。
12.字典和列表的比较
python中list是元素有序存储的序列代表,dict是元素无序存储的代表。它们都可变,是python中最灵活的两种数据类型。
但是:
- dict的元素检索、增删改速度快,不会随着元素增多、减少而改变。但缺点是内存占用大
- list的元素检索、增删改速度随着元素增多会越来越慢(当然实际影响并没有多大),但是内存占用小
换句话说,dict是空间换时间,list是时间换空间。
其实从dict和list的数据结构上很容易可以看出dict要比list占用的内存大。不考虑存储元素的实际数据空间,list存储每个元素只需一个指针共8字节(64位机器)即可保存,而dict至少需要24字节(64位机器),不仅如此,hash表结构中每个hash桶基本上会空余1/3以上的空间。
参考二:python解包
python解包可以将元组解包成可变参数,将字典解包成关键字参数,下面列列举几种使用python解包的场景
2.1 接收函数返回值
def test():
return 1, 2, 3
a, b, c = test()
print(a, b, c) # 1 2 3
函数的返回值是一个元组,左侧是三个变量,这样就会发生解包,a, b, c依次等于元组里的元素,函数的返回值有3个,被封包成了元组, 赋值语句的左侧不一定非得是3个变量
def test():
return 1, 2, 3
a, *b = test()
print(a, b) # 1 [2, 3] 变量a赋值为1, 变量b前面有一个星号,剩余的2, 3 将被解包为列表
#如果不加星号,就会报错如下:
Traceback (most recent call last):
File "C:\Users\ZY922\AppData\Roaming\JetBrains\PyCharm2022.2\scratches\01.py", line 4, in <module>
a, b = test()
ValueError: too many values to unpack (expected 2)
2.2 传递参数
def func(*args):
print(sum(args))
a = (2, 4, 6)
func(*a) # 将元组解包成可变参数
def func_2(**kwargs):
for key, value in kwargs.items():
print(key, value)
b = {'一': 1, '二': 2}
func_2(**b) # 将字典解包成关键字参数
2.3 遍历字典
my_dic = {
'一': 1,
'二': 2,
'三': 3
}
for item in my_dic.items():
print(item)
# 解包
for key, value in my_dic.items():
print(key, value)
2.4 合并两个字典
巧妙的利用解包技术,可以简单方便的将两个字典合并到一个新字典中
dic_1 = {'一': 1}
dic_2 = {'二': 2}
dic_3 = {**dic_1, **dic_2}
print(dic_3) # {'一': 1, '二': 2}
二、练习题
通过几道python字典(dict)练习题来巩固对字典的掌握, 考察你对python字典常用方法的理解和使用,比如keys(), values(),如何判断一个key是否在字典中, 如何用字典来存储并表示数据
1. 字典基本操作
字典内容如下
dic = {
'python': 95,
'java': 99,
'c': 100
}
用程序解答下面的题目
- 字典的长度是多少
- 请修改'java' 这个key对应的value值为98
- 删除 c 这个key
- 增加一个key-value对,key值为 php, value是90
- 获取所有的key值,存储在列表里
- 获取所有的value值,存储在列表里
- 判断 javascript 是否在字典中
- 获得字典里所有value 的和
- 获取字典里最大的value
- 获取字典里最小的value
- 字典 dic1 = {'php': 97}, 将dic1的数据更新到dic中
第1题,len(dic),结果为3 第2题,dic['java'] = 98,对字典里value的修改,必须通过key才可以 第3题,del dic['c'] 第4题,dic['php'] = 90 第5题,lst = list(dic.keys()) 第6题,lst = list(dic.values()) 第7题,'javascript' in dic 第8题,sum(dic.values()) 第9题,max(dic.values()) 第10题,min(dic.values()) 第11题,dic.update(dic1)
2. 字典应用(买水果)
小明去超市购买水果,账单如下
苹果 32.8
香蕉 22
葡萄 15.5
请将上面的数据存储到字典里,可以根据水果名称查询购买这个水果的费用
很简单哦,用水果名称做key,金额做value,创建一个字典
info = {
'苹果':32.8,
'香蕉': 22,
'葡萄': 15.5
}
3. 字典应用(买水果2)
小明,小刚去超市里购买水果
小明购买了苹果,草莓,香蕉,一共花了89块钱,,小刚购买了葡萄,橘子,樱桃,一共花了87块钱
请从上面的描述中提取数据,存储到字典中,可以根据姓名获取这个人购买的水果种类和总费用。
以姓名做key,value仍然是字典
info = {
'小明': {
'fruits': ['苹果', '草莓', '香蕉'],
'money': 89
},
'小刚': {
'fruits': ['葡萄', '橘子', '樱桃'],
'money': 87
}
}