python 进阶语法:集合推导式

本文围绕Python中集合(set)展开,介绍了集合的定义、特性、操作、运算及集合推导式。集合是无序且元素唯一的,操作包括添加、删除元素等,还有冰冻集合这一不可变类型。集合运算有交集、并集等,集合推导式可从已有数据序列创建新序列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

集合推导式是Python中的一种特性,它可以用来从已有的数据序列(如列表、集合或字典)创建新的数据序列。

1.  Python中集合(set)的定义

  • 集合是无序的
  • 集合的元素不能重复,所以集合中的元素是唯一的
  • 集合中不能出现可变的数据类型,集合中存放的数据类型:number,string,tuple,冰冻集合
  • 可以直接使用 {} 来定义集合
  • 可以使用 set{} 进行集合的定义和转换
  • 使用集合推导式完成集合的定义

2.  Python中集合(set)的特性

在Python中,集合(set)是一个无序的不重复元素序列,它具有以下特性:

  1. 元素的值不能改变,但可以删除和增加
  2. 集合中无重复数据
  3. 集合中的数据是无序的
  4. 集合内部会对数据元素自动按一定顺序处理,但不是自动排序
  5. 集合中没有切片和索引

3.  Python中集合(set)的操作

3.1  定义集合

vars = {123,'abc',False,'love',True,(1, 2, 3),0,3.145,123}
print(vars) # {False, True, 3.145, 'love', (1, 2, 3), 123, 'abc'}

# 从返回结果,我们发现:
# 1、无序
# 2、布尔类型true表示为1,False表示为0,布尔和数字只能存在一个,Flase在集合中表示为0,所以False和0只能存在一个
# 3、元素的值不能重复

3.2  集合转换

original_list = [1,2,3,4]
new_set = set(original_list)
print(new_set)  # {1, 2, 3, 4}
original_dict = {'a':1,'b':2,'c':3}
new_set = set(original_dict)
print(new_set)  # 返回字典的Key:{'c', 'b', 'a'}
original_tuple = (('a',1),('b',2),('c',3))
new_set = set(original_tuple)
print(new_set)  # 返回:{('b', 2), ('c', 3), ('a', 1)}

3.2  添加元素

3.2.1 添加元素到集合 add()
vars = {False, True, 3.145, 'love', (1, 2, 3), 123, 'abc'}
res = vars.add('def')
print(res)  # None
print(vars)  # {False, True, 3.145, 'abc', 'def', (1, 2, 3), 'love', 123}

首先,我们需要明确Python集合(set)的add方法并不会返回集合本身,而是返回None。所以当你尝试打印res,其结果将会是None

此外,add 方法添加元素到集合中并不会改变原始集合的顺序。同时,集合中的元素是唯一的,如果尝试添加一个已经存在的元素,那么该操作不会有任何效果。

vars = {False, True, 3.145, 'love', 'def',(1, 2, 3), 123, 'abc'}
res = vars.add('def')
print(res)
print(vars)

# 返回结果:
# None
# {False, True, 3.145, (1, 2, 3), 'love', 'def', 'abc', 123}
3.2.2  合并两个集合 update()

在Python中,集合(set)的update方法用于合并两个集合,而不是删除元素。它会添加所有不在原始集合中的元素,而不会改变原始集合中已经存在的元素。

vars = {False, True, 3.145, 'love', 'def',(1, 2, 3), 123, 'abc'}
res = vars.update({3.14,tuple([1,1,2,3,5,8])})
print(res)  # 返回:None
print(vars)  # 返回:{False, True, 3.145, 'def', 'love', 3.14, (1, 1, 2, 3, 5, 8), (1, 2, 3), 'abc', 123}

在Python中,集合(set)是一个无序的不重复元素序列。集合中的元素必须是可哈希的,这意味着它们必须是不可变的。这意味着你可以在集合中存储整数、浮点数、字符串、元组等,但你不能存储列表或其他可变的数据结构,因为它们不是不可变的。所以,为了解决这个问题,你可以将列表转换为元组,因为元组是不可变的并且是可哈希的。

3.3  删除元素

3.3.1  随机删除一个元素并返回:pop()
vars = {False, True, 3.145, 'love', 'def',(1, 2, 3), 123, 'abc'}
del_element = vars.pop()
print(del_element)
print(vars)

# 返回结果:
# False
# {True, 3.145, 'def', (1, 2, 3), 'love', 'abc', 123}
3.3.2  指定删除集合中的元素:remove()、discard()

remove() 返回None,不存在则报错

res = vars.remove('abc')
print(res)
print(vars)
vars = {False, True, 3.145, 'love', 'def',(1, 2, 3), 123, 'abc'}
del_element = vars.remove('abc')  # remove()返回none,不存在则报错
print(del_element)
print(vars)

# 返回结果:
# None
# {False, True, 'love', 3.145, 'def', (1, 2, 3), 123}

discard() 返回None,不存在不报错

vars = {False, True, 3.145, 'love', 'def',(1, 2, 3), 123, 'abc'}
del_element = vars.discard('aaa')  # remove()返回none,不存在也不会报错
print(del_element)
print(vars)

# 返回结果:
# None
# {False, True, 'def', 3.145, 'love', (1, 2, 3), 123, 'abc'}

3.3.3  清空集合 clear()
vars = {False, True, 3.145, 'love', 'def',(1, 2, 3), 123, 'abc'}
res = vars.clear()
print(res)  # 返回:None
print(vars)  # 返回:set()

3.4  计算元素个数 len()

vars = {False, True, 3.145, 'love', 'def',(1, 2, 3), 123, 'abc'}
res = len(vars)
print(res)  # 返回:8

3.5  判断元素是否存在 in、not in

vars = {False, True, 3.145, 'love', 'def',(1, 2, 3), 123, 'abc'}
res1 = 123 in vars
res2 = 'aaa' not in vars

print(res1)  # 返回:True
print(res2)  # 返回:True

3.6  集合的拷贝 copy()

vars = {False, True, 3.145, 'love', 'def',(1, 2, 3), 123, 'abc'}
res = vars.copy()
print(res)  # 返回:{False, True, 'def', 3.145, (1, 2, 3), 'abc', 'love', 123}

当前集合中的浅拷贝并不存在深拷贝的问题。因为集合中的元素都是不可变的,包括元组和冰冻集合不存在拷贝后,对集合中不可变的二级容器进行操作。

3.7  冰冻集合

在Python中,"冰冻集合"(Frozenset)是一个不可变的集合类型。它与普通的可变集合(Set)相对,是不可变的意味着一旦创建了冰冻集合,就不能更改它的内容。

3.7.1  冰冻集合的一些特性
  • 不可变性:冰冻集合是不可变的,一旦创建就不能更改。这意味着你不能添加、删除或修改冰冻集合中的元素。

  • 线程安全:由于冰冻集合是不可变的,它们在多线程环境中是线程安全的。在并发编程中,这使得它们成为存储共享数据的可靠选择。

  • 哈希性:冰冻集合是哈希的,这意味着它们可以作为字典的键或其他集合的元素。由于它们是不可变的,所以它们的哈希值不会改变。

3.7.2  冰冻集合的创建

你可以使用内置的frozenset()函数或花括号{}来创建冰冻集合。例如:

s = frozenset([1, 2, 3, 4]) 
t = frozenset((5, 6, 7, 8)) 
u = frozenset({9, 10, 11, 12})
3.7.3  冰冻集合的作用
  • 由于冰冻集合是不可变的,它们经常用于创建只读的数据结构,如哈希表中的键或作为字典的键。由于它们是不可变的,所以它们在多线程环境中是安全的,可以作为线程之间的共享数据。
  • 冰冻集合也常用于函数参数的默认值,因为它们是不可变的,所以可以确保函数参数的一致性。
3.7.6  与可变集合的区别
  • 可变集合(Set)与冰冻集合的主要区别在于可变性。可变集合是可变的,这意味着你可以添加、删除或修改集合中的元素。与此相反,冰冻集合一旦创建就是不可变的。

示例:

下面是一个简单的示例,演示了如何使用冰冻集合:

# 创建一个冰冻集合 
fs = frozenset([1, 2, 3, 4]) 
print(fs) # 输出:frozenset([1, 2, 3, 4]) 

# 由于冰冻集合是不可变的,尝试修改它会导致错误 
# fs.add(5) # AttributeError: 'frozenset' object has no attribute 'add'

总结,冰冻集合在Python中提供了一种不可变集合的类型,它常用于创建只读的数据结构、作为字典的键或在多线程环境中安全地存储数据。

4.  Python中集合(set)的运算

4.1  交集:使用 & 或 set.intersection() 或 set.intersection_update()

vars1 = {'郭富城','达尔文','张学友','黎明','爱因斯坦'}
vars2 = {'赵四','刘能','小沈阳','宋小宝','爱因斯坦','达尔文'}

# 使用 & 求两个集合相交部分
res = vars2 & vars1
print(res)  # {'达尔文', '爱因斯坦'}

# 使用 intersection() 求两个集合相交部分
res = vars2.intersection(vars1)
print(res)  # {'达尔文', '爱因斯坦'}

set.intersection() 返回交集的结果,产生新的集合。

vars1 = {'郭富城','达尔文','张学友','黎明','爱因斯坦'}
vars2 = {'赵四','刘能','小沈阳','宋小宝','爱因斯坦','达尔文'}

# 使用 intersection_update() 求两个集合相交部分
res = vars1.intersection_update(vars2)

print(res)  # None
print(vars1)  # {'爱因斯坦', '达尔文'}

set.intersection_update() 方法用于更新集合 vars1,将其修改为 vars1vars2 的交集。如果 vars1中存在某个元素不在 vars2 中,则该元素会被从 vars1 中移除。如果存在相同的元素在两个集合中,它们都会被保留。 

set.intersection_update() 没有返回值

4.2  并集:使用 | 或 union() 或 update()

vars1 = {'郭富城','达尔文','张学友','黎明','爱因斯坦'}
vars2 = {'赵四','刘能','小沈阳','宋小宝','爱因斯坦','达尔文'}

# 使用 | 求两个集合的并集,也就是把两个集合的元素全部集中起来(去重)
res = vars1 | vars2

print(res)  # {'刘能', '郭富城', '赵四', '达尔文', '爱因斯坦', '宋小宝', '小沈阳', '黎明', '张学友'}
vars1 = {'郭富城','达尔文','张学友','黎明','爱因斯坦'}
vars2 = {'赵四','刘能','小沈阳','宋小宝','爱因斯坦','达尔文'}

# 使用 set.union() 求两个集合的并集,返回一个新的集合。
res = vars1.union(vars2)

print(res)  # {'刘能', '郭富城', '赵四', '达尔文', '爱因斯坦', '宋小宝', '小沈阳', '黎明', '张学友'}
vars1 = {'郭富城','达尔文','张学友','黎明','爱因斯坦'}
vars2 = {'赵四','刘能','小沈阳','宋小宝','爱因斯坦','达尔文'}

# 使用 set.update() 求两个集合的并集,并把结果赋值给第一个集合。
res = vars1.update(vars2)
print(vars1)  # {'刘能', '郭富城', '赵四', '达尔文', '爱因斯坦', '宋小宝', '小沈阳', '黎明', '张学友'}

4.3  差集:使用 - 或 set.diffrence() 或 set.diffrence_update()

vars1 = {'郭富城','达尔文','张学友','黎明','爱因斯坦'}
vars2 = {'赵四','刘能','小沈阳','宋小宝','爱因斯坦','达尔文'}

# 使用 - 求两个集合的差集。
res = vars1 - vars2  # vars1里有,vars2里没有的
print(res)  # {'张学友', '黎明', '郭富城'}

res = vars2 - vars1  # vars2里有,vars1里没有的
print(res)  # {'赵四', '小沈阳', '刘能', '宋小宝'}
vars1 = {'郭富城','达尔文','张学友','黎明','爱因斯坦'}
vars2 = {'赵四','刘能','小沈阳','宋小宝','爱因斯坦','达尔文'}

# 使用 set.difference() 求两个集合的差集,并返回一个新的差集
res = vars1.difference(vars2)  # vars1里有,vars2里没有的
print(res)  # {'张学友', '黎明', '郭富城'}

res = vars2.difference(vars1)  # vars2里有,vars1里没有的
print(res)  # {'赵四', '小沈阳', '刘能', '宋小宝'}
vars1 = {'郭富城','达尔文','张学友','黎明','爱因斯坦'}
vars2 = {'赵四','刘能','小沈阳','宋小宝','爱因斯坦','达尔文'}

# 使用 set.difference() 求两个集合的差集,并把结果赋值vars1。
res = vars1.difference_update(vars2)  # vars1里有,vars2里没有的
print(vars1)  # {'张学友', '黎明', '郭富城'}

 4.4  对称差集:使用^ 或 symmtric_difference() 或symmetric_difference_update()

  • 对称差集,也称为对称差,是集合运算中的一种概念。对于两个集合A和B,它们的对称差集定义为A和B中所有不属于A∩B的元素的集合,记为A△B。换句话说,A△B包含的是那些属于A或者属于B,但不同时属于两者的元素。数学表达式为:A△B = (A∪B) - (A∩B) 或者 A△B = (A - B) ∪ (B - A)。
  • 这个概念在多个领域中有应用,例如在计算机科学中,它可以用于处理和操作数据结构,如集合。在Python中,可以使用 ^ 或 symmmetric_difference()或symmmetric_difference_update()方法来计算两个集合的对称差集。这个方法返回一个新的集合,不会修改原始集合。 
vars1 = {'郭富城','达尔文','张学友','黎明','爱因斯坦'}
vars2 = {'赵四','刘能','小沈阳','宋小宝','爱因斯坦','达尔文'}

# 使用 ^ 求两个集合的对称差集,并返回一个新集合。
res = vars1 ^ vars2
print(res)  # {'赵四', '郭富城', '黎明', '小沈阳', '刘能', '宋小宝', '张学友'}
vars1 = {'郭富城','达尔文','张学友','黎明','爱因斯坦'}
vars2 = {'赵四','刘能','小沈阳','宋小宝','爱因斯坦','达尔文'}
# 使用 set.symmetric_difference() 求两个集合的对称差集,并返回一个新集合。
res = vars1.symmetric_difference(vars2)
print(res)  # {'赵四', '郭富城', '黎明', '小沈阳', '刘能', '宋小宝', '张学友'}
vars1 = {'郭富城','达尔文','张学友','黎明','爱因斯坦'}
vars2 = {'赵四','刘能','小沈阳','宋小宝','爱因斯坦','达尔文'}
# 使用 set.symmetric_difference_update() 求两个集合的对称差集,并把结果赋值给vars1。
res = vars1.symmetric_difference_update(vars2) # 返回:None
print(vars1)  # {'赵四', '郭富城', '黎明', '小沈阳', '刘能', '宋小宝', '张学友'}

5.  集合推导式

5.1  普通推导式

varset = {1,2,3,4}
newset = {i<<2 for i in varset}
print(newset)  # {8, 16, 4, 12}

# 一个整数的二进制向左移动两位,原数(十进制)与新数的关系是:新数=原数×4
# 因为集合中的元素是无序的,所以不一定是{4, 8, 12, 16}

5.2  带有条件表达式的推导式

varset = {1,2,3,4}
newset = {i<<2 for i in varset if i%2==0}
print(newset)  # {8, 16}

5.3  带有多循环的集合推导式

varsl = {1,2,3}
vars2 = {4,5,6}
newset = set()
for i in varsl:
    for j in vars2:
        print(i,j)
        newset.add(i+j)
print(newset)

# 返回结果:
# 1 4
# 1 5
# 1 6
# 2 4
# 2 5
# 2 6
# 3 4
# 3 5
# 3 6
# {5, 6, 7, 8, 9}

优化多循环为集合推导式:

varsl = {1,2,3}
vars2 = {4,5,6}

newset = {i+j for i in varsl for j in vars2}
print(newset)  # {5, 6, 7, 8, 9}

5.4  带条件表达式的多循环的集合推导式

varsl = {1,2,3}
vars2 = {4,5,6}
newset = {i+j for i in varsl for j in vars2 if i%2==0 and j%2==0}
print(newset)  # {8, 6}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我自纵横2023

您的鼓励将是我最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值