[ Python ] set集合及函数的使用
1. set类型
set 和 dict 类似,也是一组 key 的集合,但是不存储 value. 由于 key 不重复,所以,在 set 中, 没有重复的 key 集合是可变类型
(1)集合的创建
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 第一种方式创建 set 类型 >>> print ( type (set1), set1) < class 'set' > { 1 , 3 , 6 , 'z' , 'a' , 'b' } # 第二种方式创建 set 类型 >>> set2 = set ([ 'z' , 'a' , 'b' , 3 , 6 , 1 ]) >>> print ( type (set2), set2) < class 'set' > { 1 , 3 , 6 , 'z' , 'a' , 'b' } # 第三种方式创建 set 类型 >>> set3 = set ( 'hello' ) >>> print ( type (set3), set3) < class 'set' > { 'o' , 'e' , 'l' , 'h' } |
2. set 工厂函数
(1)add(self, *args, **kwargs)
新增一个元素到集合
1 2 3 4 5 6 7 | set1 = { 'a' , 'z' , 'b' , 4 , 6 , 1 } set1.add( 8 ) set1.add( 'hello' ) print (set1) # 执行结果: # {'b', 1, 'a', 4, 6, 8, 'hello', 'z'} |
(2) clear()
清空所有集合元素
1 2 3 4 5 6 | set1 = { 'a' , 'z' , 'b' , 4 , 6 , 1 } set1.clear() print (set1) # 执行结果: # set() |
(3)copy()
拷贝整个集合并赋值给变量
1 2 3 4 5 6 | set1 = { 'a' , 'z' , 'b' , 4 , 6 , 1 } set2 = set1.copy() print (set2) # 执行结果: # {1, 'a', 4, 6, 'b', 'z'} |
(4)pop()
随机删除集合中一个元素,可以通过变量来获取删除的元素
1 2 3 4 5 6 7 8 | set1 = { 'a' , 'z' , 'b' , 4 , 6 , 1 } ys = set1.pop() print ( 'set1集合:' , set1) print ( '删除的元素:' , ys) # 执行结果: # set1集合: {4, 6, 'z', 'a', 'b'} # 删除的元素: 1 |
(5)remove(self, *args, **kwargs)
删除集合中指定的元素,如果该集合内没有该元素就报错
1 2 3 4 5 6 7 8 9 10 11 12 | set1 = { 'a' , 'z' , 'b' , 4 , 6 , 1 } set1.remove( 'a' ) print (set1) set1.remove( 'x' ) print (set1) # 执行结果: # {1, 4, 6, 'b', 'z'} # Traceback (most recent call last): # File "D:/learn_python/learn_python/day13/s1.py", line 43, in <module> # set1.remove('x') # KeyError: 'x' |
(6)discard(self, *args, **kwargs)
删除集合中指定的元素,如果该集合内没有该元素也不会报错
1 2 3 4 5 6 7 8 9 | set1 = { 'a' , 'z' , 'b' , 4 , 6 , 1 } set1.discard( 'a' ) print (set1) set1.discard( 'y' ) print (set1) # 执行结果: # {1, 4, 6, 'b', 'z'} # {1, 4, 6, 'b', 'z'} |
pop() 、remove() 、 discard() 三个集合删除函数比较:
pop() 随机删除集合中一个元素remove() 删除集合中指定的元素,如果集合中没有指定的元素,程序报错!
discard() 删除集合中指定的元素,如果集合中没有指定的元素,程序正常运行。
(7) intersection & :交集; union | :并集合; difference - : 差集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | set1 = { 'a' , 'b' , 'x' , 'y' } set2 = { 'i' , 'j' , 'b' , 'a' } # 交集 print (set1 & set2) print (set1.intersection(set2)) # 执行结果: # {'a', 'b'} # {'a', 'b'} # 并集 print (set1 | set2) print (set1.union(set2)) # 执行结果: # {'y', 'j', 'a', 'b', 'x', 'i'} # {'y', 'j', 'a', 'b', 'x', 'i'} # 差集 print (set1 - set2) print (set1.difference(set2)) print (set2 - set1) print (set2.difference(set1)) # 执行结果: # {'y', 'x'} # {'y', 'x'} # {'j', 'i'} # {'j', 'i'} |
(8)difference_update ()
求差集,并赋值给源集合
1 2 3 4 5 6 7 | set1 = { 'a' , 'b' , 'x' , 'y' } set2 = { 'i' , 'j' , 'b' , 'a' } set1.difference_update(set2) print (set1) # 执行结果: # {'y', 'x'} |
(9)intersection_update()
求交集,并赋值给源集合
1 2 3 4 5 6 7 8 | set1 = { 'a' , 'b' , 'x' , 'y' } set2 = { 'i' , 'j' , 'b' , 'a' } set1.intersection_update(set2) print (set1) # 执行结果: # {'b', 'a'} |
(10)symmetric_difference() 和 ^ 符号效果一样
求交叉补集
1 2 3 4 5 6 7 8 9 | set1 = { 'a' , 'b' , 'x' , 'y' } set2 = { 'i' , 'j' , 'b' , 'a' } print ( 'symmetric_difference:' , set1.symmetric_difference(set2)) print ( '^:' , set1 ^ set2) # 执行结果: # symmetric_difference: {'x', 'i', 'y', 'j'} # ^: {'x', 'i', 'y', 'j'} |
(11)symmetric_difference_update()
求交叉补集并赋值给源集合
1 2 3 4 5 6 7 8 | set1 = { 'a' , 'b' , 'x' , 'y' } set2 = { 'i' , 'j' , 'b' , 'a' } set1.symmetric_difference_update(set2) print (set1) # 执行结果: # {'y', 'i', 'j', 'x'} |
(12)update()
更新集合,参数为可迭代对象
1 2 3 4 5 6 7 | set1 = { 'a' , 'b' , 'x' , 'y' } set1.update(( 'hello' , 'world' )) print (set1) # 执行结果: # {'hello', 'world', 'b', 'a', 'y', 'x'} |
add() 和 update() 比较:
add(): 只能添加一个元素到集合
update(): 可以添加多个元素到集合,参数为 iterable
使用 frozenset 定义不可变集合
1 2 3 4 5 | s = frozenset ( 'hello' ) print (s) # 执行结果: # frozenset({'h', 'e', 'o', 'l'}) |
使用 frozenset 定义的集合,没有 add 或者 pop 等方法
3. 函数
(1)函数表现形式
python中函数的定义方法:
1 2 3 4 | def test(x): "The function definitions" x + = 1 return x |
def: 定义函数关键字
test: 函数名(): 内可定义参数"": 文档描述(非必要,强烈建议添加函数信息描述)
x+=1 : 泛指代码块或程序处理逻辑
return: 定义返回值
调用运行:可以带参数也可以不带函数名()
使用函数的好处:
代码重用
保持一致性,易维护
可扩展
函数返回值:
返回值 = 0 : 返回 None
返回值 = 1 : 返回 object
返回值数 > 1: 返回 tuple
(2)函数的参数
建议参考:廖老师python3函数的参数
4. 全局变量和局部变量
如果函数的内容无 global 关键字,优先读取局部变量,能读取全局变量,无法对全局变量重新赋值 NAME='FFF',但是对于可变类型,可以对内部元素进行操作;
如果函数中有 global 关键字,变量本质上就是全局变量,可读取可赋值 NAME='fff'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | name = 'hkey' def test1(): name = 'xiaofei' print (name) def test2(): global name name = 'xxxx' test1() test2() print ( 'name:' , name) # 执行结果: # xiaofei # name: xxxx |
如果函数内无 global 关键字:
(1)有声明局部变量
1 2 3 4 5 6 7 8 9 10 | NAME = [ 'xiaofei' , 'hkey' ] def test(): NAME = 'sky' print ( 'name:' , NAME) test() # 执行结果: # name: sky |
(2)无声明局部变量
对于可变类型,可以对内部元素进行操作;
1 2 3 4 5 6 7 8 9 10 | NAME = [ 'xiaofei' , 'hkey' ] def test(): NAME.append( 'sky' ) print ( 'name:' , NAME) test() # 执行结果: # name: ['xiaofei', 'hkey', 'sky'] |
如果函数内有 global 关键字
(1)有声明局部变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | NAME = [ 'xiaofei' , 'hkey' ] def test(): # 获取全局变量 NAME global NAME # 打印全局变量 NAME print ( 'global NAME:' , NAME) # 将全局变量 NAME 修改为 'test_func' NAME = 'test_func' # 打印修改后的全局变量 print ( 'name:' , NAME) test() # 执行结果: # global NAME: ['xiaofei', 'hkey'] |
(2)无声明局部变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | NAME = [ 'xiaofei' , 'hkey' ] def test(): # 获取全局变量 NAME global NAME # 打印全局变量 NAME print (NAME) # 修改全局变量为 ['sky'] NAME = [ 'sky' ] # 追加全局变量 NAME.append( 'blue' ) # 打印修改后的全局变量 print (NAME) test() # 执行结果: ##['sky','blue'] |
在代码中我们规定,全局变量名全部使用大写,而局部变量用小写,这边就避免变量名的混淆;
(3)nonlocal 关键字用来在函数或者其他作用域中使用外层变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | def outer(): num = 10 def inner(): nonlocal num # nonlocal 关键字声明 num = 100 # 修改作用域 num 使用方法和 global 一致 print (num) inner() print (num) # 该 num 已经在 inner() 中修改过的 outer() # 执行结果: # 100 # 100 |
5. 递归函数
(1)函数即变量
1 2 3 4 5 6 7 8 | def test(): pass t = test # 把函数当作值 赋值给变量 t print (t) # 执行结果: # <function test at 0x00000245A2FBA048> |
(2)递归函数
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都写成循环的方式,但循环的逻辑不如递归清晰。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | def fact(n): if n = = 1 : return 1 return n * fact(n - 1 ) print (fact( 5 )) # 执行过程如下: # # ===> fact(5) # ===> 5 * fact(4) # ===> 5 * (4 * fact(3)) # ===> 5 * (4 * (3 * fact(2))) # ===> 5 * (4 * (3 * (2 * fact(1)))) # ===> 5 * (4 * (3 * (2 * 1))) # ===> 5 * (4 * (3 * 2)) # ===> 5 * (4 * 6) # ===> 5 * 24 # ===> 120 |
递归函数就像问路一样,有去有回。A问B,B在问C,C知道答案返回给B,B在返回给A
必须有一个明确的结束条件
每次进入更深一层的递归时,问题规模相比上次递归应有所减少
递归效率不高
(3)尾递归优化
尾递归是指,在函数返回的时候,调用自身本身,并且,return 语句不能包含表达式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | def fact(n): return fact_iter(n, 1 ) def fact_iter(num, product): if num = = 1 : return product # return 语句不能包含表达式。递归本身无论调用多少次,都只占用一个栈帧 return fact_iter(num - 1 , num * product) # 运行过程: # fact(5) # ===> fact_iter(5, 1) # ===> fact_iter(4, 5) # ===> fact_iter(3, 20) # ===> fact_iter(2, 60) # ===> fact_iter(1, 120) # ===>120 |
本文作者:hukey
本文链接:https://www.cnblogs.com/hukey/p/9242339.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2017-06-29 [ Python - 6 ] 正则表达式实现计算器功能
2016-06-29 【 APACHE 】 Apache2.4.x版本虚拟主机配置