Jean's Blog

一个专注软件测试开发技术的个人博客

0%

Python dict和set的操作

字典

字典(dict),一种映射对象(mapping)类型,键值对的容器。

五种创建方法

创建 dict 的方法很简单,使用一对中括号 {},键值对中间用冒号,每项间使用逗号分割。

1. 直接使用{}创建

1
2
3
4
5
6
>>> empty = {}
>>> empty
{}
>>> dic = {'a':1, 'b':2, 'c':3}
>>> dic
{'a': 1, 'b': 2, 'c': 3}

2. 使用dict()构造函数

1
2
>>> dict(a=1, b=2, c=3)
{'a': 1, 'b': 2, 'c': 3}

3. 键值对 + 关键字参数

第一个参数为字典,后面是一系列关键字参数,如 c=3

1
2
>>> dict({'a':1, 'b':2}, c=3, d=4)
{'a': 1, 'b': 2, 'c': 3, 'd': 4}

4. 可迭代对象

列表,元素又为一个元组,后面再加一系列关键字参数。

1
2
>>> dict([('a',1), ('b',2)], c=3)
{'a': 1, 'b': 2, 'c': 3}

5. fromkeys()方法

已知键集合(keys),values 为初始值:

1
2
3
4
>>> {}.fromkeys(['k1', 'k2', 'k3'], [1, 2, 3])
{'k1': [1, 2, 3], 'k2': [1, 2, 3], 'k3': [1, 2, 3]}
>>> {'a':1, 'b':2}.fromkeys(['c', 'd'], [1, 2])
{'c': [1, 2], 'd': [1, 2]}

遍历字典

1
2
3
4
5
6
7
>>> d = {'a':1, 'b':2, 'c':3}
>>> for key, val in d.items():
... print(key, val)
...
a 1
b 2
c 3

获取所有键集合(keys)

1
2
3
4
5
6
# 方法一:
>>> set(d)
{'c', 'b', 'a'}
# 方法二:
>>> set(d.keys())
{'c', 'b', 'a'}

获取所有值集合(values)

1
2
>>> set(d.values())
{1, 2, 3}

判断键是否在字典中

1
2
3
4
5
6
7
8
9
10
# 判断键 c 在 d 中?
>>> if 'c' in d:
... print('键c在字典d中')
...
键c在字典d中
# 判断键 c 不在 d 中?
>>> if 'e' not in d:
... print('键e不在字典d中')
...
键e不在字典d中

获取某键对应的值

1
2
>>> d.get('c')
3

添加、修改或删除一个键值对

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 添加元素
>>> d['c'] = 3
>>> d
{'a': 1, 'b': 2, 'c': 3}
# 修改元素
>>> d['c'] = 4
>>> d
{'a': 1, 'b': 2, 'c': 4}
# 删除一个键值对,方法1
>>> del d['c']
>>> d
{'a': 1, 'b': 2}
# 删除一个键值对,方法2
>>> d.pop('b')
2
>>> d
{'a': 1}

字典视图

字典自带的三个方法 d.items()、d.keys()、d.values(),分别返回如下对象:

1
2
3
4
5
6
7
8
9
>>> d = {'a':1, 'b':2, 'c':3}
>>> d
{'a': 1, 'b': 2, 'c': 3}
>>> d.keys()
dict_keys(['a', 'b', 'c'])
>>> d.values()
dict_values([1, 2, 3])
>>> d.items()
dict_items([('a', 1), ('b', 2), ('c', 3)])

它们都是原字典的视图,修改原字典对象,视图对象的值也会发生改变。

1
2
3
a = {'a':1, 'b':2, 'c':3}
# 创建字典的键集合视图
key_lst = a.keys()

代码可视图如下所示:

image-20220408152600534

删除键 b,由代码执行可视化图可看到,视图对象 key_lst 值也发生改变。

image-20220408152624832

items(),也是返回一个视图对象:

1
2
a = {'a':1, 'b':2, 'c':3}
items = a.items()

image-20220408152650640

修改字典,可看到视图对象 items 的值也会改变:

1
a['c']=4

image-20220408152713988

字典的键

所有对象都能作为字典的键吗?

如果一个列表对象 lst 试图作为字典的键,会出现什么问题。

下面,实验一下:

1
2
3
4
5
>>> lst = [1,2]
>>> d = {lst:'ok?'}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

会抛出如上 TypeError 异常:不可哈希的类型 list。

因为列表是可变对象,而可变对象是不可哈希的,所以会抛出如上异常。

结论:可哈希的对象才能作为字典的键,不可哈希的对象不能作为字典的键。

集合

集合是一种不允许元素出现重复的容器。

创建

与字典(dict)类似,集合(set)也是由一对花括号({})创建。但是,容器内的元素不是键值对。

1
a = {1, 2, 3}

示意图如下:

image-20220408152737877

同字典类似,集合内的元素必须是可哈希类型(hashable)。

这就意味着 list、dict 等不可哈希的对象不能作为集合的元素。

1
2
3
4
>>> {[1, 2]}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

另一种创建集合的方法,是通过 Python 的内置的 set 函数,参数类型为可迭代对象 Iterable。

1
2
>>> set([1, 3, 5, 7])
{1, 3, 5, 7}

常用方法

集合自带的方法与数学中的集合操作比较类似,提供查找集合间的并、交、差集、子集判断。

求并集union

1
2
3
4
5
>>> a = {1, 3, 5, 7}
>>> b, c = {3, 4, 5, 6}, {6, 7, 8, 9}
>>> d = a.union(b, c)
>>> d
{1, 3, 4, 5, 6, 7, 8, 9}

image-20210928140910307

求差集difference

1
2
3
4
5
>>> a = {1, 3, 5, 6}
>>> b, c = {3, 4, 5, 6}, {6, 7, 8, 9}
>>> d = a.difference(b, c)
>>> d
{1}

image-20210928141119618

求交集intersection

1
2
3
4
5
>>> a = {1, 3, 5, 7}
>>> b, c = {3, 4, 5, 6}, {6, 7, 8, 9}
>>> d = a.intersection(b, c)
>>> d
{}

image-20210928141353447

a 是 b 的子集吗?issubset

1
2
3
4
5
6
7
8
>>> a = {1, 3, 5, 7}
>>> b = {3, 4, 5, 6}
>>> a.issubset(b)
False
>>> a.issubset(a)
True
>>> a.issubset({1, 3, 5, 7, 8})
True