什么是集合?

  • Python中内置数据结构之一
  • 和列表,字典一样都是可变序列
  • 集合相当于没有值(value)的字典,用{}花括号定义,里面数据是无序的

创建集合的方法:

  • 直接用{}花括号定义,和字典不同的是,字典的元素是键(key)值(value)对,集合是单独的元素,相当于只有一个键,不允许数据重复
  • 用内置函数set()创建

{}花括号创建

a = {10, 20, 30, 30, 40, 50, 50}
print(a, type(a))

运行结果:

  • {40, 10, 50, 20, 30} <class 'set'>

{}花括号包裹数据,里面的数据同样用分隔符,逗号分隔,元素是键(key)值(value)对的是字典,单独一个键的是集合,运行后会自动去重,数据位置也是经过hash(哈希函数)计算后得出的,所以运行后不是按我们填写的顺序输出的,数据类型为set

用内置函数set()创建

a1 = set(range(6))
print(a1, type(a1))
a2 = set([10, 20, 30, 30, 40, 50, 50])
print(a2, type(a2))
a3 = set((10, 20, 30, 40, 50))
print(a3, type(a3))
a4 = set({10, 20, 30, 40, 50})
print(a4, type(a4))
a5 = set('python')
print(a5, type(a5))
a6 = set()
print(a6, type(a6))

运行结果:

  • {0, 1, 2, 3, 4, 5} <class 'set'>
  • {40, 10, 50, 20, 30} <class 'set'>
  • {40, 10, 50, 20, 30} <class 'set'>
  • {50, 20, 40, 10, 30} <class 'set'>
  • {'y', 'o', 'h', 't', 'p', 'n'} <class 'set'>
  • set() <class 'set'>

从上列代码来看,可以直接用set()函数把range()函数创建的序列转换成集合,也可以把列表,元组等直接转换成集合,set()函数括号内也可以直接是一个{}花括号定义的集合,当把字符串转换成集合的时候,字符会被拆分成一个个成为单独的元素,空集合不能直接用没数据的{}花括号,那样代表的是空字典,只能用括号内没有参数的set()函数来创建空集合,同样的,如果输出的集合里面有重复数据,会自动去重,数据位置只能由hash(哈希函数)自动计算,不是按我们填写数据的顺序输出的

集合元素的判断:

可以用布尔运算符innot in来判断一个元素在集合中是否存在

a = {10, 20, 30, 40}
print(a)
print(30 in a)
print(30 not in a)

运行结果:

  • {40, 10, 20, 30}
  • True
  • False

多次写到过,不再做解析

集合元素的添加操作:

  • 调用add()一次添加一个元素
  • 调用update()一次添加至少一个元素
a = {10, 20, 30, 40}
print(a)
a.add(50)
print(a)
a.update({60, 70})
print(a)

运行结果:

  • {40, 10, 20, 30}
  • {40, 10, 50, 20, 30}
  • {70, 40, 10, 50, 20, 60, 30}

可以从结果看出,输出的顺序不是按我们填写的顺序或者大小顺序排列的,由hash(哈希函数)计算后自动排列的,调用add()添加元素,括号内参数只能是一个整数,浮点数或者字符串等。调用update()添加元素,括号内参数只能是包括一个元素或以上的可变序列对象,可以把要添加的元素集合成一个可变序列对象,也可以填写几个可变序列对象,分隔符,逗号隔开,添加的元素如果和原集合有重复,输出时会自动去重

集合元素的删除操作:

  • 调用remove()方法一次删除一个指定元素,如果要删除的元素不存在,会报错
  • 调用discard()方法一次删除一个指定元素,如果要删除的元素不存在,不会报错
  • 调用pop()方法一次删除一个任意元素
  • 调用clear()方法清空集合
  • 调用del+空格+集合对应的变量名直接删除集合和对应的变量
a = {10, 20, 30, 40, 50, 60, 70, 80, 90}
print(a)
a.remove(30)
print(a)
a.discard(50)
print(a)
a.pop()
print(a)
a.pop()
print(a)
a.clear()
print(a)
del a
# print(a)

运行结果:

  • {70, 40, 10, 80, 50, 20, 90, 60, 30}
  • {70, 40, 10, 80, 50, 20, 90, 60}
  • {70, 40, 10, 80, 20, 90, 60}
  • {40, 10, 80, 20, 90, 60}
  • {10, 80, 20, 90, 60}
  • set()

调用remove()方法和discard()方法的区别是,在要删除的元素在集合中不存在时,前者会报错,后者不会。调用pop()方法说明是删除一个任意元素,其实是删除hash(哈希函数)计算后的输出位置排最前面的一个元素,括号内不能填写参数,因为我们无法判断hash计算后的排序,所以表述为删除任意一个元素。最后调用del的方法删除集合和对应的变量后,没有再次输出,因为输出会提示变量未定义,报错

集合之间的关系:

两个集合是否相等,用比较运算符==!=来判断

a1 = {10, 20, 30, 40}
print(a1)
a2 = {30, 20, 40, 10}
print(a2)
print(a1 == a2)
print(a1 != a2)

运行结果:

  • {40, 10, 20, 30}
  • {40, 10, 20, 30}
  • True
  • False

之前说过,集合的输出顺序是hash(哈希函数)计算得出的,不是按我们填写的顺序输出的,看运行结果也可以看出来,所以只要两个集合中的元素数量对等且全部相同,就是相等的

一个集合是否是另一个集合的子集

a1 = {10, 20, 30, 40, 50}
a2 = {10, 20, 30}
a3 = {10, 20, 90}
a4 = {100, 200, 300}
print(a2.issubset(a1))
print(a3.issubset(a1))

运行结果:

  • True
  • False

调用issubset()方法判断前者是否是后者的子集,原理和数学一样,不在解析

一个集合是否是另一个集合的超集

a1 = {10, 20, 30, 40, 50}
a2 = {10, 20, 30}
a3 = {10, 20, 90}
a4 = {100, 200, 300}
print(a1.issuperset(a2))
print(a1.issuperset(a3))

运行结果:

  • True
  • False

调用issuperset()方法判断前者是否是后者的超集,原理和数学一样,不在解析

一个集合是否和另一个集合“没有”交集

a1 = {10, 20, 30, 40, 50}
a2 = {10, 20, 30}
a3 = {10, 20, 90}
a4 = {100, 200, 300}
print(a1.isdisjoint(a3))
print(a1.isdisjoint(a4))

运行结果:

  • False
  • True

调用isdisjoint()方法判断前者和后者是否“没有交集”,原理和数学一样,不在解析,需要注意的是,这次没有交集的判断结果为True

集合的数据操作:

集合之间的数学操作有交集,并集,差集,对称差集

操作示意图

图片中带颜色的位置就是求解后剩下的元素位置,跟数学一样

a1 = {10, 20, 30, 40}
a2 = {20, 30, 40, 50, 60}
print(a1.intersection(a2))  # 交集
print(a1 & a2)  # 交集
print(a1.union(a2))  # 并集
print(a1 | a2)  # 并集
print(a1.difference(a2))  # 差集
print(a1 - a2)  # 差集
print(a1.symmetric_difference(a2))  # 对称差集
print(a1 ^ a2)  # 对称差集

运行结果:

  • {40, 20, 30}
  • {40, 20, 30}
  • {40, 10, 50, 20, 60, 30}
  • {40, 10, 50, 20, 60, 30}
  • {10}
  • {10}
  • {50, 10, 60}
  • {50, 10, 60}

每一种操作方法都有简化的符号可以作为替代,效果一样,如上代码所示

集合生成式:

a = {i for i in range(1, 10)}
print(a)

运行结果:

  • {1, 2, 3, 4, 5, 6, 7, 8, 9}

和列表生成式基本相同,除了括号不同,不做解析

最后修改:2021 年 12 月 14 日 12 : 41 AM