集合与字典类型

阅读 110

Python 提供了多种容器类型,除了上一节中的列表和元组,还有集合和字典。不同的是,他们没有顺序,不能根据序列号来查询数据。

集合 set

集合类型,定义和数学上的集合定义相似,表示由不重复元素组成的无序的集,其核心是不重复,无序。用 set() 来创建。也可以使用 包含元素的大括号 {a} ,但是不能是空大括号。空大括号默认表示字典类型,下面会讲到。

>>> a = set()
>>> type(a)
<class 'set'>
>>> a = {}
>>> type(a)
<class 'dict'>
>>> a = {'a'}
>>> type(a)
<class 'set'>
>>> a.add('a')
>>> a
{'a'}
>>> a.add('b')
>>> a
{'b', 'a'}
>>> a.add('a')
>>> a
{'b', 'a'}

支持常见的集合运算。交集、并集、补集等。

>>> a = {1,2,3,4,5}
>>> b = {1,3,5,7,9}
>>> a
{1, 2, 3, 4, 5}
>>> b
{1, 3, 5, 7, 9}
>>> a - b
{2, 4}
>>> a | b  # 并集:a,b 中的所有元素
{1, 2, 3, 4, 5, 7, 9}
>>> a & b  # 交集:同时出现在 a,b 中的元素
{1, 3, 5}
>>> a ^ b  # 异或,只出现在 a,或者 b 中的元素,不出同时出现
{2, 4, 7, 9}

和 list 类似,集合也支持推导式,只是返回的结果是 set。

>>> a = {x for x in 'hello set' if x not in 'list'}
>>> a
{'h', 'e', ' ', 'o'}

Python 提供了一种特殊的字典,frozenset,初始化完成后就不能改动。

>>> a = frozenset({1,2,3,4})
>>> a
frozenset({1, 2, 3, 4})
>>> a.add(10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'frozenset' object has no attribute 'add'

字典 dict

字典是一种映射关系,将可以 hash 的值(简单的理解就是不可变的值)映射到一个对象上。也就是保存 key - value 对,key 必须是唯一的,value 可以是任意值。字典的特点在于可以根据 key 快速找到 value。

一个对象的哈希值如果在其生命周期内绝不改变,就被称为 可哈希 (它需要具有 __hash__() 方法),并可以同其他对象进行比较(它需要具有 __eq__() 方法)。可哈希对象必须具有相同的哈希值比较结果才会相同。

可以使用 {} 或者 dict() ,来创建空字典。

>>> a = {}
>>> b = dict()
>>> a == b
True
>>> a is b
False
>>> type(a)
<class 'dict'>

也可以初始化包含值的字典。

>>> a = dict(a=1, b=2)
>>> a
{'a': 1, 'b': 2}
>>> b = {'a':1, 'b':2}
>>> b
{'a': 1, 'b': 2}
>>> a == b
True
>>> a is b
False

key 可以是数字,字符,元组。但是不能是集合,列表,或者字典。

>>> a = (1,2,)
>>> type(a)
<class 'tuple'>
>>> b = {1:1, 'a': 1, a: 12}
>>> b
{1: 1, 'a': 1, (1, 2): 12}


对于不能 hash 的 key,则会抛出 TypeError。

>>> a = {[]:1}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> a = {{a,}: 1}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
>>> a = {{1:1}: 1}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'

字典的增删改查。现在使用字典类型保存小明同学的考试成绩。

>>> a = {'yuwen': 100, 'shuxue': 90, 'dili': 98}
>>> a
{'yuwen': 100, 'shuxue': 90, 'dili': 98}

获取单一科目的成绩。可以直接使用 key 获取,也可以使用 get 方法获取。

>>> a['yuwen']
100
>>> a.get('yuwen')
100

区别是对于不存在的 key,前者或抛出异常 KeyError,而后者如果不存在就会返回 None,也可以指定默认返回值。

>>> a['waiyu']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'waiyu'
>>> s = a.get('waiyu')
>>> s is None
True
>>> a.get('waiyu', 60)
60

如果现在需要添加新的科目成绩。

>>> a = {'yuwen': 100, 'shuxue': 90, 'dili': 98}
>>> a['waiyu'] = 99
>>> a
{'yuwen': 100, 'shuxue': 90, 'dili': 98, 'waiyu': 99}

修改成绩的操作也是一样的,同时也可以使用 update 方法。

>>> a['waiyu'] = 100
>>> a
{'yuwen': 100, 'shuxue': 90, 'dili': 98, 'waiyu': 100}
>>> a.update(waiyu=99)
>>> a
{'yuwen': 100, 'shuxue': 90, 'dili': 98, 'waiyu': 99}
>>> a.update({'waiyu': 99})
>>> a
{'yuwen': 100, 'shuxue': 90, 'dili': 98, 'waiyu': 99}

删除数据,使用 del 操作。del 在 Python 中专门表示删除内容,以可以用来删除字典,列表等内容。

>>> del a['waiyu']
>>> a
{'yuwen': 100, 'shuxue': 90, 'dili': 98}
>>> del a
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined

判断科目是否存在,可以直接使用 in 操作。 in 在 Python 中专门用来判断内容是否存在,列表,字典,集合都可以使用 in 操作。

>>> a = {'yuwen': 100, 'shuxue': 90, 'dili': 98}
>>> 'yuwen' in a
True
>>> 'waiyu' in a
False

字典也支持推导式。形式上和列表推导式有一点点区别。

>>> a = {k : k*k for k in range(5)}
>>> a
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

字典的常用方法。字典常用 keys 返回 key 的集合,类型是 dict_keys;values 返回 value 的列表,类型是 dict_values;使用 items 返回包含 key 和value 的键值列表,类型是 dict_items。

>>> a = {'yuwen': 100, 'shuxue': 90, 'dili': 98}
>>> a
{'yuwen': 100, 'shuxue': 90, 'dili': 98}
>>> a.keys()
dict_keys(['yuwen', 'shuxue', 'dili'])
>>> a.values()
dict_values([100, 90, 98])
>>> a.items()
dict_items([('yuwen', 100), ('shuxue', 90), ('dili', 98)])

注意这里返回的是视图对象,当字典的值发生改动时,视图的内容也会变化。注意,a 的值改动时,b 的值直接变为最新的值了。这里的视图,只是保存了样子,并没有直接保存内容。和数据库视图的概念类似。

>>> a = {'yuwen': 100, 'shuxue': 90, 'dili': 98}
>>> b = a.keys()
>>> b
dict_keys(['yuwen', 'shuxue', 'dili'])
>>> a['waiyu'] = 100
>>> b
dict_keys(['yuwen', 'shuxue', 'dili', 'waiyu'])

字典使用的场景很多,Python 提供了 defaultdict(设置默认值的字典),OrderedDict(根据添加属性排序的字典)。

小结

集合和字典也是最常用的 Python 内置数据类型,并且提供了丰富的操作支持。在开发中要注意区别各种容器类型的特点,选择合适的类型。