本章目录
- Part One:基本概念
- Part Two:常用方法
在Java里,存在一种K(key)-V(value)对应关系(键值对)的数据结构,称之为Map。
而Python中也有类似的结构,那就是dict(字典)。之所以叫字典,是因为我们可以把key想象成字典中的单词,而value就是该单词的释义了。所以呢,一个单词可以对应一个或者多个释义,但是这些释义只能通过单词来查询。
需要注意的是,字典中key都是唯一的。每个key只会对应1个value。所谓的一个单词对应多个释义,是因为这个释义是List类型的,而不是说有多个value。
字典具有极快的查找速度。
基本概念
- 空字典
# Python使用{}或者dict()来创建空字典
dict1 = {}
# type可以查看对象的类型
print(type(dict1))
dict2 = dict()
print(type(dict2))
结果为:
- 初始化字典
# 可以用key-value的形式初始化字典
dict_nba = {"LeBron James": "Cleveland Cavaliers", "James Harden": "Houston Rockets",
"Stephen Curry": "Golden State Warriors"}
# 打印字典
print(dict_nba)
# 打印该键对应的值
print(dict_nba["James Harden"])
结果为
{'LeBron James': 'Cleveland Cavaliers', 'James Harden': 'Houston Rockets', 'Stephen Curry': 'Golden State Warriors'}
Houston Rockets
- 插入键值对
# dict()创建字典的方式之一
# 此处用dict方式而不是{}方式,是因为{}方式会报This dictionary creation could be rewritten as a dictionary literal.警告
dict_nba = dict([("LeBron James", "Cleveland Cavaliers"), ("James Harden", "Houston Rockets"),
("Stephen Curry", "Golden State Warriors")])
# 直接给 dict[key] 赋值即可完成插入操作
dict_nba["Kevin Durant"] = "Golden State Warriors"
print(dict_nba)
结果为:
{'LeBron James': 'Cleveland Cavaliers', 'James Harden': 'Houston Rockets', 'Stephen Curry': 'Golden State Warriors', 'Kevin Durant': 'Golden State Warriors'}
- 更新键值
dict_nba = dict([("LeBron James", "Cleveland Cavaliers"), ("James Harden", "Houston Rockets"),
("Stephen Curry", "Golden State Warriors")])
# 给同样的key,指定另外一个值。结果为key相同,值覆盖
dict_nba["Kevin Durant"] = "Oklahoma City Thunder"
print(dict_nba)
结果为:
{'LeBron James': 'Cleveland Cavaliers', 'James Harden': 'Houston Rockets', 'Stephen Curry': 'Golden State Warriors', 'Kevin Durant': 'Oklahoma City Thunder'}
- 字典没有顺序
当我们print一个字典时,Python并不一定按照插入键值的先后顺序进行显示,因为字典中的键本身不一定是有序的。如果想让字典有序,需要制定相应的规则对key排序。
dict_nba = dict([("LeBron James", "Cleveland Cavaliers"), ("James Harden", "Houston Rockets"),
("Stephen Curry", "Golden State Warriors")])
# 字典不支持使用数字index来查看字典中的值,因为数字也是可以作为索引的,容易造成混淆
print(dict_nba[0])
结果为:
KeyError: 0
- 键必须是不可变的
Python中要求字典中的键值对的键必须是不可变的,而值可以是任意的Python对象。
这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。
要保证hash的正确性,作为key的对象就不能变。
不过,键的类型可以是不同类型的。
dict_nba = dict([("LeBron James", "Cleveland Cavaliers"), ("James Harden", "Houston Rockets"),
("Stephen Curry", "Golden State Warriors")])
dict_nba[1] = "Oklahoma City Thunder"
dict_nba["Dwight Howard"] = ["Orlando Magic", "Los Angeles Lakers", "Houston Rockets",
"Atlanta Hawks", "Charlotte Hornets"]
print(dict_nba)
结果为:
{'LeBron James': 'Cleveland Cavaliers', 'James Harden': 'Houston Rockets', 'Stephen Curry': 'Golden State Warriors', 1: 'Oklahoma City Thunder', 'Dwight Howard': ['Orlando Magic', 'Los Angeles Lakers', 'Houston Rockets', 'Atlanta Hawks', 'Charlotte Hornets']}
- 适合做键的类型
通常,我们习惯使用字符串或者整数来作为键。
List是可变的,不能作为键,会报unhashable type异常,就是无法哈希化。
浮点数虽然也是不可变的,但是最好不要使用浮点数作为键,因为浮点数在进行数学运算后会损失精度,比如1.1 + 2.2和3.3其实是两个不同的键。
元组不可变,且是有序的,可以作为键,但是使用时必须保证元祖内不包含list。
总之,作为key必须可以被哈希化,所以键或者键中的内容都是可不变的。
flights = dict([
(("Beijing", "Shanghai"), "21:15 PM"),
(("Shanghai", "Beijing"), "6:15 PM")])
flights["New"] = "Unknown"
flights[1] = "Hello"
print(flights)
结果为:
{('Beijing', 'Shanghai'): '21:15 PM', ('Shanghai', 'Beijing'): '6:15 PM', 'New': 'Unknown', 1: 'Hello'}
- 列表和字典的区别
列表 | 字典 | |
---|---|---|
顺序 | 能保证存放顺序 | 无序 |
访问方法 | 索引 | key |
查找和插入速度 | 随着元素的增加而增加 | 不会随着key的增加而变慢, 速度恒定 |
占用空间 | 占用内存小 | 内存开销稍大 |
常用方法
- in方法查询字典中是否有该键
dict_nba = dict([("LeBron James", "Cleveland Cavaliers"), ("James Harden", "Houston Rockets"),
("Stephen Curry", "Golden State Warriors")])
name = "LeBron James"
# in方法检索key,返回值为True或者False
if name in dict_nba:
print(name, "is an American professional basketball player for the", dict_nba[name] + ".")
else:
print("Not a NBA player.")
结果为:
LeBron James is an American professional basketball player for the Cleveland Cavaliers.
- get方法查询字典中是否有该键
dict_nba = dict([("LeBron James", "Cleveland Cavaliers"), ("James Harden", "Houston Rockets"),
("Stephen Curry", "Golden State Warriors")])
name = "LeBron James"
# get方法检索key,若存在直接返回该key对应的value
print(dict_nba.get(name))
# get方法检索key,若不存在直接返回None
if dict_nba.get("Kevin Love"):
print(name, "is an American professional basketball player for the", dict_nba[name] + ".")
else:
print("Not a NBA player.")
# 或者可通过修改get(key, default = None)中的default值来指定默认返回值
print(dict_nba.get("Kevin Love", "Unknown."))
结果为:
Cleveland Cavaliers
Not a NBA player.
Unknown.
- pop,del方法删除键值对
dict_nba = dict([("LeBron James", "Cleveland Cavaliers"), ("James Harden", "Houston Rockets"),
("Stephen Curry", "Golden State Warriors")])
# pop方法和get方法类似,也是pop(key, default = None)形式的
# 同样的,若key存在,则从字典中删除该key和value,并返回该key对应的value;若key不存在,返回default的值
print(dict_nba.pop("LeBron James"))
print(dict_nba)
# 已从表中删除,所以返回Unknown
print(dict_nba.pop("LeBron James", "Unknown."))
# del也可以从字典中删除键值对,并且无返回值
del dict_nba["James Harden"]
print(dict_nba)
结果为:
Cleveland Cavaliers
{'James Harden': 'Houston Rockets', 'Stephen Curry': 'Golden State Warriors'}
Unknown.
{'Stephen Curry': 'Golden State Warriors'}
- update方法更新字典
dict_nba = dict([("LeBron James", "Cleveland Cavaliers"), ("James Harden", "Houston Rockets"),
("Stephen Curry", "Golden State Warriors")])
# update方法,参数为字典,无返回值
# 也可用于修改value
temp = {"Dwight Howard": ["Orlando Magic", "Los Angeles Lakers", "Houston Rockets", "Atlanta Hawks", "Charlotte Hornets"],
"Kobe Bryant": "Retired",
"LeBron James": ["Miami Heat", "Cleveland Cavaliers"]}
dict_nba.update(temp)
print(dict_nba)
结果为:
{'LeBron James': ['Miami Heat', 'Cleveland Cavaliers'], 'James Harden': 'Houston Rockets', 'Stephen Curry': 'Golden State Warriors', 'Dwight Howard': ['Orlando Magic', 'Los Angeles Lakers', 'Houston Rockets', 'Atlanta Hawks', 'Charlotte Hornets'], 'Kobe Bryant': 'Retired'}