目录

人生苦短 | Python字典和集合归纳整理

字典

字典是什么?

Python中定义字典使用大括号{},字典内部的每个元素由两个部分组成:键:值,其中键只能是int, float, str, tuple等必须是可哈希的数据。如下所示,

1
>>> d1 = {"name":'Dawn', 3:20, 3.4:'male', (1,2):3}

当然创建字典还可以通过dict()方法,这与{}创建的字典是一致的:

1
2
3
4
5
6
>>> d1 = {"name":'Dawn', 'age':20, 'gender':'male'}
>>> d2 = dict({"name":'Dawn', 'age':20, 'gender':'male'})
>>> d3 = dict([("name", 'Dawn'), ('age', 20), ('gender','male')])
>>> d4 = dict(name='Dawn', age=20, gender='male')
>>> d1 == d2 == d3 == d4
True

在Python3.7+,字典被确定为有序,而3.6之前是无序的,其长度大小可变,元素可以任意地删减和改变。在3.6中,字典有序是一个implementation detail,在3.7才正式成为语言特性,因为3.6中无法100%确保其有序性。同时相比于列表和元组,字典的性能更优,特别是对于查找、添加和删除操作,字典都能在常数时间复杂度内完成。

字典的相关操作

集合

集合是什么?

Python中定义集合时同样使用大括号{},但是通过{}创建集合时需要注意,{}里面必须有初始值,否则是dict字典类型。同时集合内部的元素,只能存放int, float, str, tuple等必须是可哈希的数据,列表是不可哈希的。

1
2
3
4
5
6
>>> set1 = {}
>>> set2 = {1,2,3}
>>> type(set1)
<class 'dict'>
>>> type(set2)
<class 'set'>

当然我们还可以通过set()函数来创建集合,不需要用{}的方式。这两种方法创建的集合是一样的。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
>>> s1 = {1, 2, 3}
>>> s2 = set([1, 2, 3])
>>> s3 = set('dog')
>>> s1
{1, 2, 3}
>>> s2
{1, 2, 3}
>>> s3
{'g', 'o', 'd'}
>>> s1 == s2
True

除此之外集合具有以下特征:

  • 集合内部的元素是无序(采用的哈希表存储的),所以不能使用索引、切片等操作
  • 集合内部的元素具有唯一性,不允许元素重复出现。
  • set类型本身不可哈希
1
2
3
4
5
>>> s1 = {1, 2, 3, 'a', 'b', 'c', 7, 8, 9}
>>> for val in s1:
	print(val, end=" ")

1 2 3 c b 7 8 9 a 	# 输出结果可以看出set是无序的

集合的相关操作

增加集合中的元素

使用set.add()方法可以像集合中添加元素,但是由于集合内部的元素具有唯一性,所以当添加相同元素的时候,集合中还是只有一个该元素。

1
2
3
4
5
6
7
>>> s1 = {1, 2, 3}
>>> s1.add(4)
>>> s1
{1, 2, 3, 4}
>>> s1.add(4)
>>> s1
{1, 2, 3, 4}

删除集合中的元素

set.remove()

当删除不存在的元素的时,会报错。

1
2
3
4
5
6
7
8
9
>>> s1 = {1, 2, 3, 'a', 'b', 'c', 7, 8, 9}
>>> s1.remove(1)
>>> s1
{2, 3, 'c', 'b', 7, 8, 9, 'a'}
>>> s1.remove(5)
Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    s1.remove(5)
KeyError: 5

set.discard()

相比set.remove()操作,删除不存在的元素时不报错,只是执行删除操作失败。

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

in关键字

判断一个元素是否在集合中,在的话返回True

1
2
3
4
5
>>> s1 = {1, 2, 3}
>>> 1 in s1
True
>>> 4 in s1
False

交叉并补

set.intersection()方法或者&符号

求两个集合的交集。

1
2
3
4
5
6
7
8
>>> s1 = {1,2,3,4,5,6}
>>> s2 = {5,6,7,8,9,0}
>>> s1.intersection(s2)
{5, 6}
>>> s2.intersection(s1)
{5, 6}
>>> s1 & s2
{5, 6}

set.difference()方法或者-符号

求两个集合的差集。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
>>> s1 = {1,2,3,4,5,6}
>>> s2 = {5,6,7,8,9,0}
>>> s1.difference(s2)
{1, 2, 3, 4}
>>> s2.difference(s1)
{0, 8, 9, 7}
>>> s1 - s2
{1, 2, 3, 4}
>>> s2 - s1
{0, 8, 9, 7}

set.union()方法或者|符号

求两个集合的并集。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
>>> s1 = {1,2,3,4,5,6}
>>> s2 = {5,6,7,8,9,0}
>>> s1.union(s2)
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> s2.union(s1)
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> s1 | s2
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> s2 | s1
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

set.issubset()

检查一个集合是否为另一个集合的子集。

set.issuperset()

检查一个集合是否为另一个集合的超集(如果一个集合S2中的每一个元素都在集合S1中,且集合S1中可能包含S2中没有的元素,则集合S1就是S2的一个超集,反过来,S2是S1的子集)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
>>> s1 = {1, 2, 3}
>>> s2 = {1, 2, 3, 4, 5}
>>> s1.issubset(s2)
True
>>> s2.issuperset(s1)
True
>>> s2.issubset(s1)
False
>>> s1.issuperset(s2)
False

冰冻集合

不可以进行任何修改操作的集合,其他属性与集合完全一致。

1
2
3
4
>>> s1 = {1, 2, 3}
>>> s1 = frozenset(s1)
>>> s1
frozenset({1, 2, 3})

本文参考

  1. cnblogs_Python数据结构:集合