集合数据类型专题

  • Python搬砖之旅(7th day):集合数据类型专题
  • 第一章 集合的概念与创建
  • 1.1 集合的创建
  • 1.2 将可迭代对象转化为集合
  • 1.3 在集合中添加元素
  • 1.4 在集合中删除元素
  • 1.5 访问集合中的元素
  • 第二章 集合的运算
  • 2.1 使用 in 运算符判断集合中是否存在某元素
  • 2.2 使用set.intersection()及运算符"&"计算交集
  • 2.3 使用set.union()及运算符"|"计算并集
  • 2.4 使用set.difference()及运算符"-"计算差集
  • 2.5 使用set.symmetric_difference()及运算符"^"计算对称差集
  • 2.6 使用set.issubset()及运算符"<"判断是否为对方子集
  • 2.7 使用set.issuperset()及运算符">"判断是否为对方父集
  • 第三章 集合与字典的异同点
  • 3.1 集合与字典的相同点
  • 3.2 集合与字典的不同点


Python搬砖之旅(7th day):集合数据类型专题

第一章 集合的概念与创建

集合是一种无序的可变的数据集合,它与字典一样,使用一对花括号或称为大括号来包裹数据元素。
在集合中,每一个元素都是唯一的,即是说,在集合中,每一个元素都是不可重复的。

1.1 集合的创建

虽然集合和字典都可以使用花括号或称为大括号来作为标志,但是在创建空集合的时候,并不能使用{}来创建空集合。在Python中,{}代表的是空字典而不是空集合;要创建空集合,只能调用set()方法创建
集合中的元素可以是数字型、字符串型、以及元组等不可变对象,但是不能是列表、字典、以及集合本身。
集合中的元素是不允许重复的

# 创建空集合的错误打开方式
>>> set_demo = {}
>>> print(type(set_demo))  # 使用{}实际上创建的是一个空字典
<class 'dict'>

# 创建空集合的正确打开方式
>>> set_demo = set()
>>> print(type(set_demo))  # 使用set()创建空集合
<class 'set'>

# 集合中的元素可以是数字型、字符串型、以及元组,但是不能是列表、字典、以及集合本身。
>>> set_demo = {123, 12.3, "123",(1, 2, 3)}
>>> set_demo
{'123', 123, 12.3, (1, 2, 3)}

# 集合中的元素是不允许重复的
>>> set_demo = {1, 2, 3, 4, 5}  # 正常的集合创建方式
>>> print("正常的集合:", set_demo)
正常的集合: {1, 2, 3, 4, 5}
# 打印集合中的元素个数
>>> print(len(set_demo))
5
# 如果集合中存在重复的元素,程序不会报错,但是重复的元素会被抛弃。
>>> set_demo = {1, 2, 3, 4, 5, 3, 4, 5}  # 正常的集合创建方式
>>> print("正常的集合:", set_demo)
正常的集合: {1, 2, 3, 4, 5}

1.2 将可迭代对象转化为集合

我们可以使用set()方法,将列表、元组、字符串等可迭代对象中的元素转化为集合,如果原来的数据中存在重复元素,那么在转换为集合的时候,只保留其中一个。

# 使用set()方法将可迭代对象转化为集合数据类型
set_demo = set(range(1,6)) # 将range()函数对象转化为集合类型
print("转化后的集合:", set_demo)
>>> 转化后的集合: {1, 2, 3, 4, 5}

tup_temp = (1,2,3,4,5)     # 将元组转化为集合类型
set_demo = set(tup_temp)   # set方法中的参数应该是可迭代对象
print("转化后的集合:", set_demo)
>>> 转化后的集合: {1, 2, 3, 4, 5}

lis_temp = [1, 1, 2, 2, 3, 3]  # 将列表转化为集合类型
set_demo = set(tup_temp)   # set方法创建集合后可以实现对元素的去重
print("转化后的集合:", set_demo)
>>> 转化后的集合: {1, 2, 3}

str_temp = "Mary's lovely Dog."   # 将字符串转化为集合类型
set_demo = set(str_temp)   # 转化后字符的出现顺序是随机的
print("转化后的集合:", set_demo)
>>> 转化后的集合: {'y', "'", 'v', 'a', 'r', 's', 'e', 'D', 'g', 'M', 'l', '.', ' ', 'o'}

问题1:如果在列表中嵌套有字典或列表元素,在使用set()方法将其转化为集合的时候,会发生什么变化呢?答案是:不能哈希化,就是说不能将元素为字典或子列表的可迭代对象创建为集合。

>>> li_1 = [{'name':'Allen'}, {'age':16}]
>>> set_demo = set(li_1)
Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    set_demo = set(li_1)
TypeError: unhashable type: 'dict'

>>> li_2 = [[1,2,3], [1, 3, 4]]
>>> set_demo = set(li_2)
Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    set_demo = set(li_2)
TypeError: unhashable type: 'list'

问题2:有些同学可能会说,元组可以作为集合的元素,那我把列表等可迭代对象改为元组是否可行呢?答案同样是不可以。

>>> tup_1 = ([1, 2, 3], [1, 3, 4])
>>> set_demo = set(tup_1)
Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    set_demo = set(tup_1)
TypeError: unhashable type: 'list'

>>> tup_2 = ({'name':'Allen'}, {'age':16})
>>> set_demo = set(tup_2)
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    set_demo = set(tup_2)
TypeError: unhashable type: 'dict'

综上所述:使用set()方法将可迭代对象转化为集合的时候,可迭代对象的元素必须是不可修改的数据类型。

>>> tup_3 = (123, 12.3, "123", (1, 2, 3))
>>> set_demo = set(tup_3)
>>> print(set_demo)
{'123', 123, 12.3, (1, 2, 3)}

1.3 在集合中添加元素

在集合中,添加元素可以使用set.add()方法

>>> set_demo = {1, 2, 3, 4, 5}
>>> set_demo.add(6)
>>> print(set_demo)
{1, 2, 3, 4, 5, 6}

# 注意,向集合中添加已有元素会自动去重
>>> set_demo.add(5)
>>> print(set_demo)
{1, 2, 3, 4, 5, 6}

如果向集合中添加一个已有的元素,则集合不会保留这个元素。

在集合中,可以使用set.update()方法,将一个可迭代对象更新到已有的集合中。当然,也是经过去重的。

>>> set_demo = {1, 2, 3}
# 注意,update()方法的参数必须是一个可迭代对象
>>> set_demo.update([3, 4, 5, 6])
>>> print(set_demo)
{1, 2, 3, 4, 5, 6}

# 注意,update()方法可以加入字典作为参数,但是,键值对中只有key键被保留
>>> set_demo = {1, 2, 3}
>>> set_demo.update({4:"4", 5:"5"})
>>> print(set_demo)
{1, 2, 3, 4, 5}

1.4 在集合中删除元素

我们可以使用set.remove()方法或set.discard()方法删除指定的集合元素,
或者使用pop()方法删除随机的集合元素 。
其他的方法还有,set.clear()清空集合元素;del set 删除集合

>>> set_demo = {1, 2, 3, 4, 5, 6}  
>>> set_demo.remove(6)  # 使用remove()方法删除指定元素
>>> print(set_demo)
{1, 2, 3, 4, 5}

>>> set_demo = {1, 2, 3, 4, 5, 6}  
>>> set_demo.discard(6)  # 使用discard()方法删除指定元素
>>> print(set_demo)
{1, 2, 3, 4, 5}

# 使用pop()方法会删除随机元素,并返回被删除的元素值
>>> set_demo = {"1", "2", "3", "4", "5"}
>>> set_demo.pop()
'3'
>>> print(set_demo)
{'5', '1', '2', '4'}

注意:
1,set.remove()方法和set.discard()很相似,但是,set.remove()方法在删除一个不属于集合的元素时会报错,而set.discard()会忽视该操作,并不会报错。

>>> set_demo = {1, 2, 3, 4, 5, 6}
>>> set_demo.remove(7)
Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    set_demo.remove(7)
KeyError: 7
>>> set_demo.discard(7)

2,set.pop()方法会有所变化:
如果集合的元素都是数字, 删除时, 删掉的是最小的数字, 其余数字升序排列;
如果集合的元素是非数字, 删除时, 删掉的是随机的元素, 其余元素随机排列;
如果集合里既有数字又有非数字元素,,删除时,若删掉的是数字, 则一定是删掉了最小的,其他数字升序排列, 非数字元素随机排列;若删掉的是非数字,则一定是随机删掉了一个非数字元素, 其他数字升序排列,非数字元素则随机排列。
参考:https://www.runoob.com/python3/ref-set-pop.html

1.5 访问集合中的元素

注意:我们在对集合的操作中,不能访问某个具体的元素,因为集合既不支持下标索引也不支持字典那样的通过键值对获取元素。
但是,因为集合本身是一个可迭代对象,所以我们可以使用for循环来遍历。

>>> set_demo = {1, 2, 3, 4, 5}
>>> for i in set_demo:
	print(i, end = " ")
1 2 3 4 5

第二章 集合的运算

2.1 使用 in 运算符判断集合中是否存在某元素

>>> set_demo = {123, 12.3, "123", (1, 2, 3)}
>>> print(123 in set_demo)
True
>>> print("123" not in set_demo)
False

2.2 使用set.intersection()及运算符"&"计算交集

交集是指,既存在于A集合中的元素,又存在于B集合中的元素。
其数学表达式为:A ∩ B

>>> set_a = {1, 2, 3, 4, 5}
>>> set_b = {3, 4, 5, 6, 7}

# 求set_a 与 set_b 的交集
>>> print(set_a.intersection(set_b))
{3, 4, 5}
# 求set_a 与 set_b 的交集
>>> print(set_a & set_b)
{3, 4, 5}

2.3 使用set.union()及运算符"|"计算并集

交集是指,将A集合与B集合中的元素相加形成一个新的集合,同时去除重复的元素。
其数学表达式为:A ∪ B

>>> set_a = {1, 2, 3, 4, 5}
>>> set_b = {3, 4, 5, 6, 7}

# 求set_a 与 set_b 的并集
>>> print(set_a.union(set_b))
{1, 2, 3, 4, 5, 6, 7}
# 求set_a 与 set_b 的并集
>>> print(set_a | set_b)
{1, 2, 3, 4, 5, 6, 7}

2.4 使用set.difference()及运算符"-"计算差集

差集是指,从A集合中去掉同时存在于B集合中的元素。
其数学表达式为:A - B = A - (A ∩ B)
同理,B - A = B - (A ∩ B)

>>> set_a = {1, 2, 3, 4, 5}
>>> set_b = {3, 4, 5, 6, 7}

# 求set_a 与 set_b 的差集
>>> print(set_a.difference(set_b))
{1, 2}
>>> print(set_b.difference(set_a))
{6, 7}
# 求set_a 与 set_b 的差集
>>> print(a - b)
{1, 2}
>>> print(b - a)
{6, 7}

2.5 使用set.symmetric_difference()及运算符"^"计算对称差集

对称差集是指,A 与 B集合中,同时不属于对方的元素集合。
其数学表达式为:A △ B = (A∪B) - (A ∩ B)
同理, A △ B = B △ A

>>> set_a = {1, 2, 3, 4, 5}
>>> set_b = {3, 4, 5, 6, 7}

# 求set_a 与 set_b 的对称差集
>>> print(set_a.symmetric_difference(set_b))
{1, 2, 6, 7}
>>> print(set_b.symmetric_difference(set_a))
{1, 2, 6, 7}

# 求set_a 与 set_b 的对称差集
>>> print(set_a ^ set_b)
{1, 2, 6, 7}
>>> print(set_b ^ set_a)
{1, 2, 6, 7}

2.6 使用set.issubset()及运算符"<"判断是否为对方子集

A集合中的所有元素都包含在B集合中,则称A集合为B集合的子集。
其数学表达式为:A ⊂ B,等同于 B ⊃ A

>>> set_a = {1, 2, 3}
>>> set_b = {1, 2, 3, 4, 5}
>>> set_a.issubset(set_b)
True
>>> set_a < set_b
True

注意:判断元素是否属于集合使用 in, 但是判断集合是否为子集不能使用 in

2.7 使用set.issuperset()及运算符">"判断是否为对方父集

A集合中包含有B集合的所有元素,则称A集合为B集合的父集。
其数学表达式为:A ⊃ B,等同于 B ⊂ A

>>> set_a = {1, 2, 3, 4, 5}
>>> set_b = {1, 2, 3}
>>> set_a.issuperset(set_b)
True
>>> set_a > set_b
True

第三章 集合与字典的异同点

3.1 集合与字典的相同点

1,都是"无序"的数据集合,也就是说,集合和字典中的元素都是随机存储的;
2,都不能使用下标或切片来访问元素或元素片段;
3,集合中的元素,字典中的键,都是必须是“不可修改”的数据类型,也就是说,列表、字典、集合这三种数据类型不能作为集合中的元素或字典中的键。
4,集合中的元素,字典中的键都是"不可重复"的,即唯一性。
5,都不可以对元素进行排序。

3.2 集合与字典的不同点

1,虽然集合与字典元素都使用"{}"包含元素,但是{}只代表空字典,set()才代表空集合;
2,集合中表现为单个元素,字典中表现为键值对。