Python字典

Python 字典(dict)是一种无序的、可变的序列,它的元素以“键值对(key-value)”的形式存储。相对地,列表(list)和元组(tuple)都是有序的序列,它们的元素在底层是挨着存放的。

字典类型是 Python 中唯一的映射类型。

字典中,习惯将各元素对应的索引称为键(key),各个键对应的元素称为值(value),键及其关联的值称为“键值对”。

总的来说,字典类型所具有的主要特征如表。

主要特征 解释
通过键而不是通过索引来读取元素 字典类型有时也称为关联数组或者散列表(hash)。它是通过键将一系列的值联系起来的,这样就可以通过键从字典中获取指定项,但不能通过索引来获取。
字典是任意数据类型的无序集合 和列表、元组不同,通常会将索引值 0 对应的元素称为第一个元素,而字典中的元素是无序的。
字典是可变的,并且可以任意嵌套 字典可以在原处增长或者缩短(无需生成一个副本),并且它支持任意深度的嵌套,即字典存储的值也可以是列表或其它的字典。
字典中的键必须唯一 字典中,不支持同一个键出现多次,否则只会保留最后一个键值对。
字典中的键必须不可变 字典中每个键值对的键是不可变的,只能使用数字、字符串或者元组,不能使用列表。

Python 中的字典类型相当于 Java 或者 C++ 中的 Map 对象。

和列表、元组一样,字典也有它自己的类型。Python 中,字典的数据类型为 dict,通过 type() 函数即可查看:

1
2
a = {'one': 1, 'two': 2, 'three': 3}  #a是一个字典类型
type(a) # <class 'dict'>

创建字典

1.使用 { } 创建字典

由于字典中每个元素都包含两部分,分别是键(key)和值(value),因此在创建字典时,键和值之间使用冒号:分隔,相邻元素之间使用逗号,分隔,所有元素放在大括号{ }中。

1
dictname = {'key':'value1', 'key2':'value2', ..., 'keyn':valuen}

其中dictname表示字典变量名,keyn: valuen表示各个元素的键值对。需要注意的是,同一字典中的各个键必须唯一,不能重复。

1
2
3
4
5
6
7
8
9
#使用字符串作为key
scores = {'数学': 95, '英语': 92, '语文': 84}
print(scores) # {'数学': 95, '英语': 92, '语文': 84}
#使用元组和数字作为key
dict1 = {(20, 30): 'great', 30: [1,2,3]}
print(dict1) # {(20, 30): 'great', 30: [1, 2, 3]}
#创建空元组
dict2 = {}
print(dict2) # {}

可以看到,字典的键可以是整数、字符串或者元组,只要符合唯一和不可变的特性就行;字典的值可以是 Python 支持的任意数据类型。

2.通过 fromkeys() 方法创建字典

还可以使用dict字典类型提供的fromkeys()方法创建带有默认值的字典:

1
dictname = dict.fromkeys(list,value=None)

其中,list参数表示字典中所有键的列表(list);value参数表示默认值,如果不写,则为空值None

1
2
3
knowledge = ['语文', '数学', '英语']
scores = dict.fromkeys(knowledge, 60)
print(scores) # {'语文': 60, '英语': 60, '数学': 60}

可以看到,knowledge列表中的元素全部作为了scores字典的键,而各个键对应的值都是 60。这种创建方式通常用于初始化字典,设置value的默认值。

3.通过 dict() 映射函数创建字典

通过dict()函数创建字典的写法有多种,下面列出了常用的几种方式,它们创建的都是同一个字典a

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 写法1
# str 表示字符串类型的键,value 表示键对应的值。使用此方式创建字典时,字符串不能带引号。
a = dict(str1=value1, str2=value2, str3=value3)

# 写法2
#方式1
demo = [('two',2), ('one',1), ('three',3)]
#方式2
demo = [['two',2], ['one',1], ['three',3]]
#方式3
demo = (('two',2), ('one',1), ('three',3))
#方式4
demo = (['two',2], ['one',1], ['three',3])
a = dict(demo)
# 向 dict() 函数传入列表或元组,而它们中的元素又各自是包含 2 个元素的列表或元组,其中第一个元素作为键,第二个元素作为值。

# 方法3
keys = ['one', 'two', 'three'] #还可以是字符串或元组
values = [1, 2, 3] #还可以是字符串或元组
a = dict( zip(keys, values) )
# 通过应用 dict() 函数和 zip() 函数,可将前两个列表转换为对应的字典。

注意,无论采用以上哪种方式创建字典,字典中各元素的键都只能是字符串、元组或数字,不能是列表。列表是可变的,不能作为键。

如果不为dict()函数传入任何参数,则代表创建一个空的字典:

1
2
3
# 创建空的字典
d = dict()
print(d) # {}

访问字典

列表和元组是通过下标来访问元素的,而字典不同,它通过键来访问对应的值。因为字典中的元素是无序的,每个元素的位置都不固定,所以字典也不能像列表和元组那样,采用切片的方式一次性访问多个元素。

1
dictname[key]

其中,dictname表示字典变量的名字,key表示键名。注意,键必须是存在的,否则会抛出异常。

1
2
3
4
tup = (['two',26], ['one',88], ['three',100], ['four',-59])
dic = dict(tup)
print(dic['one']) #键存在
print(dic['five']) #键不存在

运行结果:

1
2
3
4
5
88
Traceback (most recent call last):
File "C:\Users\mozhiyan\Desktop\demo.py", line 4, in <module>
print(dic['five']) #键不存在
KeyError: 'five'

除了上面这种方式外,Python 更推荐使用dict类型提供的get()方法来获取指定键对应的值。当指定的键不存在时,get()方法不会抛出异常。

1
dictname.get(key[,default])

其中,dictname表示字典变量的名字;key表示指定的键;default用于指定要查询的键不存在时,此方法返回的默认值,如果不手动指定,会返回None

1
2
a = dict(two=0.65, one=88, three=100, four=-59)
print( a.get('one') ) # 88

注意,当键不存在时,get()返回空值None,如果想明确地提示用户该键不存在,那么可以手动设置get()的第二个参数:

1
2
a = dict(two=0.65, one=88, three=100, four=-59)
print( a.get('five', '该键不存在') ) # 该键不存在

删除字典

和删除列表、元组一样,手动删除字典也可以使用del关键字:

1
2
3
4
a = dict(two=0.65, one=88, three=100, four=-59)
print(a)
del a
print(a)

运行结果:

1
2
3
4
5
{'two': 0.65, 'one': 88, 'three': 100, 'four': -59}
Traceback (most recent call last):
File "C:\Users\mozhiyan\Desktop\demo.py", line 4, in <module>
print(a)
NameError: name 'a' is not defined

Python 自带垃圾回收功能,会自动销毁不用的字典,所以一般不需要通过del来手动删除。

字典基本操作

由于字典属于可变序列,所以我们可以任意操作字典中的键值对。Python 中,常见的字典操作有以下几种:

  • 向现有字典中添加新的键值对。
  • 修改现有字典中的键值对。
  • 从现有字典中删除指定的键值对。
  • 判断现有字典中是否存在指定的键值对。

字典是由一个一个的key-value构成的,key是找到数据的关键,Python 对字典的操作都是通过key来完成的。

字典添加键值对

为字典添加新的键值对很简单,直接给不存在的key赋值即可:

1
dictname[key] = value

对各个部分的说明:

  • dictname表示字典名称。
  • key表示新的键。
  • value表示新的值,只要是 Python 支持的数据类型都可以。
1
2
3
4
5
6
7
8
a = {'数学':95}
print(a) # {'数学': 95}
#添加新键值对
a['语文'] = 89
print(a) # {'数学': 95, '语文': 89}
#再次添加新键值对
a['英语'] = 90
print(a) # {'数学': 95, '语文': 89, '英语': 90}

字典修改键值对

Python 字典中键(key)的名字不能被修改,我们只能修改值(value)。

字典中各元素的键必须是唯一的,因此,如果新添加元素的键与已存在元素的键相同,那么键所对应的值就会被新的值替换掉,以此达到修改元素值的目的。

1
2
3
4
a = {'数学': 95, '语文': 89, '英语': 90}
print(a) # {'数学': 95, '语文': 89, '英语': 90}
a['语文'] = 100
print(a) # {'数学': 95, '语文': 100, '英语': 90}

可以看到,字典中没有再添加一个{'语文':100}键值对,而是对原有键值对{'语文': 89}中的value做了修改。

Python字典删除键值对

如果要删除字典中的键值对,还是可以使用del语句。

1
2
3
4
5
# 使用del语句删除键值对
a = {'数学': 95, '语文': 89, '英语': 90}
del a['语文']
del a['数学']
print(a) # {'英语': 90}

判断字典中是否存在指定键值对

如果要判断字典中是否存在指定键值对,首先应判断字典中是否有对应的键。判断字典是否包含指定键值对的键,可以使用innot in运算符。
需要指出的是,对于dict而言,innot in运算符都是基于key来判断的。

1
2
3
4
5
a = {'数学': 95, '语文': 89, '英语': 90}
# 判断 a 中是否包含名为'数学'的key
print('数学' in a) # True
# 判断 a 是否包含名为'物理'的key
print('物理' in a) # False

通过in(或not in)运算符,我们可以很轻易地判断出现有字典中是否包含某个键,如果存在,由于通过键可以很轻易的获取对应的值,因此很容易就能判断出字典中是否有指定的键值对。

字典方法

字典的数据类型为dict,我们可使用dir(dict)来查看该类型包含哪些方法:

1
2
dir(dict)
['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

keys()、values() 和 items() 方法

这三个方法都用来获取字典中的特定数据:

  • keys()方法用于返回字典中的所有键(key);
  • values()方法用于返回字典中所有键对应的值(value);
  • items()用于返回字典中所有的键值对(key-value)。
1
2
3
4
scores = {'数学': 95, '语文': 89, '英语': 90}
print(scores.keys()) # dict_keys(['数学', '语文', '英语'])
print(scores.values()) # dict_values([95, 89, 90])
print(scores.items()) # dict_items([('数学', 95), ('语文', 89), ('英语', 90)])

可以发现,keys()、values()items()返回值的类型分别为dict_keys、dict_valuesdict_items

需要注意的是,它们的返回值并不是我们常见的列表或者元组类型,因为 Python 3.x 不希望用户直接操作这几个方法的返回值。

如果想使用这三个方法返回的数据,一般有下面两种方案:

  1. 使用list()函数,将它们返回的数据转换成列表:
    1
    2
    3
    a = {'数学': 95, '语文': 89, '英语': 90}
    b = list(a.keys())
    print(b) # ['数学', '语文', '英语']
  2. 使用for in循环遍历它们的返回值:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    a = {'数学': 95, '语文': 89, '英语': 90}
    for k in a.keys():
    print(k,end=' ')
    print("\n---------------")
    for v in a.values():
    print(v,end=' ')
    print("\n---------------")
    for k,v in a.items():
    print("key:",k," value:",v)
    运行结果为:
    1
    2
    3
    4
    5
    6
    7
    数学 语文 英语
    ---------------
    95 89 90
    ---------------
    key: 数学 value: 95
    key: 语文 value: 89
    key: 英语 value: 90

copy() 方法

copy()方法返回一个字典的拷贝,也即返回一个具有相同键值对的新字典:

1
2
3
a = {'one': 1, 'two': 2, 'three': [1,2,3]}
b = a.copy()
print(b) # {'one': 1, 'two': 2, 'three': [1, 2, 3]}

可以看到,copy()方法将字典a的数据全部拷贝给了字典b

注意,copy()方法所遵循的拷贝原理,既有深拷贝,也有浅拷贝。拿拷贝字典a为例,copy()方法只会对最表层的键值对进行深拷贝,也就是说,它会再申请一块内存用来存放{'one': 1, 'two': 2, 'three': []};而对于某些列表类型的值来说,此方法对其做的是浅拷贝,也就是说,b中的[1,2,3]的值不是自己独有,而是和a共有。

1
2
3
4
5
6
7
8
9
10
a = {'one': 1, 'two': 2, 'three': [1,2,3]}
b = a.copy()
#向 a 中添加新键值对,由于b已经提前将 a 所有键值对都深拷贝过来,因此 a 添加新键值对,不会影响 b。
a['four']=100
print(a) # {'one': 1, 'two': 2, 'three': [1, 2, 3], 'four': 100}
print(b) # {'one': 1, 'two': 2, 'three': [1, 2, 3]}
#由于 b 和 a 共享[1,2,3](浅拷贝),因此移除 a 中列表中的元素,也会影响 b。
a['three'].remove(1)
print(a) # {'one': 1, 'two': 2, 'three': [2, 3], 'four': 100}
print(b) # {'one': 1, 'two': 2, 'three': [2, 3]}

从运行结果不难看出,对a增加新键值对,b不变;而修改a某键值对中列表内的元素,b也会相应改变。

update() 方法

update()方法可以使用一个字典所包含的键值对来更新己有的字典。

在执行update()方法时,如果被更新的字典中己包含对应的键值对,那么原value会被覆盖;如果被更新的字典中不包含对应的键值对,则该键值对被添加进去。

1
2
3
a = {'one': 1, 'two': 2, 'three': 3}
a.update({'one':4.5, 'four': 9.3})
print(a) # {'one': 4.5, 'two': 2, 'three': 3, 'four': 9.3}

从运行结果可以看出,由于被更新的字典中已包含keyone的键值对,因此更新时该键值对的value将被改写;而被更新的字典中不包含keyfour的键值对,所以更新时会为原字典增加一个新的键值对。

pop() 和 popitem() 方法

pop()popitem()都用来删除字典中的键值对,不同的是,pop()用来删除指定的键值对,而popitem()用来随机删除一个键值对:

1
2
dictname.pop(key)
dictname.popitem()

其中,dictname表示字典名称,key表示键。

1
2
3
4
5
6
a = {'数学': 95, '语文': 89, '英语': 90, '化学': 83, '生物': 98, '物理': 89}
print(a) # {'数学': 95, '语文': 89, '英语': 90, '化学': 83, '生物': 98, '物理': 89}
a.pop('化学')
print(a) # {'数学': 95, '语文': 89, '英语': 90, '生物': 98, '物理': 89}
a.popitem()
print(a) # {'数学': 95, '语文': 89, '英语': 90, '生物': 98}

对 popitem() 的说明

其实,说popitem()随机删除字典中的一个键值对是不准确的,虽然字典是一种无须的列表,但键值对在底层也是有存储顺序的,popitem()总是弹出底层中的最后一个key-value,这和列表的pop()方法类似,都实现了数据结构中“出栈”的操作。

setdefault() 方法

setdefault()方法用来返回某个key对应的value

1
dictname.setdefault(key, defaultvalue)

说明,dictname表示字典名称,key表示键,defaultvalue表示默认值(可以不写,不写的话是None)。

当指定的key不存在时,setdefault()会先为这个不存在的key设置一个默认的defaultvalue,然后再返回defaultvalue

也就是说,setdefault()方法总能返回指定key对应的value

  • 如果该key存在,那么直接返回该key对应的value
  • 如果该key不存在,那么先为该key设置默认的defaultvalue,然后再返回该key对应的defaultvalue
1
2
3
4
5
6
7
8
9
10
11
a = {'数学': 95, '语文': 89, '英语': 90}
print(a) # {'数学': 95, '语文': 89, '英语': 90}
#key不存在,指定默认值
a.setdefault('物理', 94)
print(a) # {'数学': 95, '语文': 89, '英语': 90, '物理': 94}
#key不存在,不指定默认值
a.setdefault('化学')
print(a) # {'数学': 95, '语文': 89, '英语': 90, '物理': 94, '化学': None}
#key存在,指定默认值
a.setdefault('数学', 100)
print(a) # {'数学': 95, '语文': 89, '英语': 90, '物理': 94, '化学': None}
打赏
  • Copyrights © 2017-2023 WSQ
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信