Python基础(五)集合与函数
一、Set集合
set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。下面一起看一下set的定义和使用方法:
(一),set定义
1
2
3
4
5
6
|
s1 = { 11 , 22 , 33 } #定义集合 s2 = set ([ 11 , 22 , 33 , 11 , 33 ]) #不能有重复key值 print (s1,s2) { 33 , 11 , 22 } { 33 , 11 , 22 } |
(二),set的方法
1,在集合中添加元素(add)
1
2
3
4
5
|
s1 = set ([ 11 , 22 , 33 ]) s1.add( 44 ) #添加元素 print (s1) { 33 , 11 , 44 , 22 } |
2,clear、copy跟之前的类型一样,clear是清空集合中元素,copy是浅拷贝,不再举例说明
3, 判断A中存在B中不存在的方法(difference)
1
2
3
4
5
6
|
s1 = set ([ 11 , 22 , 33 ]) s2 = set ([ 22 , 33 , 44 ]) s3 = s1.difference(s2) #判断S1中存在,S2中不存在的值赋值给S3 print (s3) { 11 } |
4,从当前集合中删除和B中相同的元素(difference_update)
1
2
3
4
5
6
|
s1 = set ([ 11 , 22 , 33 ]) s2 = set ([ 22 , 33 , 44 ]) s1.difference_update(s2) #删除S1中和S2中相同的元素 print (s1) { 11 } |
5,取A集合和B集合的交集( intersection )
1
2
3
4
5
6
7
8
|
s1 = set ([ 11 , 22 , 33 ]) s2 = set ([ 22 , 33 , 44 ]) s3 = s1.intersection(s2) print (s3) { 22 , 33 } #取S1和S2的交集,交集也有update用法和ifference用法相同 |
6,判断A、B两个集合中有无交集,没有交集返回True,相反返回Fasle( isdisjoint )
1
2
3
4
5
6
|
s1 = set ([ 11 , 22 , 33 ,]) s2 = set ([ 22 , 33 , 44 ,]) s3 = s1.isdisjoint(s2) #如果没有交集,返回True,相反返回False print (s3) Fasle |
7,移除集合中的元素,不存在不报错(discard)
1
2
3
4
5
6
|
s1 = set ([ 11 , 22 , 33 , 44 ]) s1.discard( 44 ) #移除指定元素,不存在不保错 s1.discard( 55 ) print (s1) { 33 , 11 , 22 } |
8,随机删除集合中的元素(pop)
1
2
3
4
5
|
s1 = set ([ 11 , 22 , 33 , 44 ,]) s1.pop() #pop随机删除,不建议使用 print (s1) { 11 , 44 , 22 } |
9,移除集合的元素,与discard不同的是,元素不存在会报错(remove)
1
2
3
4
5
|
s1 = set ([ 11 , 22 , 33 ]) s1.remove( 44 ) #推荐使用discard print (s1) KeyError: 44 |
10,取A中没有的和B中没有的,又叫对称差集。(symmetric_difference)
1
2
3
4
5
6
|
s1 = set ([ 11 , 22 , 33 ,]) s2 = set ([ 22 , 33 , 44 ,]) s3 = s1.symmetric_difference(s2) #取对称差集赋值给S3 print (s3) { 11 , 44 } |
11,将A、B并在一起取它们的并集(union)
1
2
3
4
5
6
|
s1 = set ([ 11 , 22 , 33 ,]) s2 = set ([ 22 , 33 , 44 ,]) s3 = s1.union(s2) #取并集 print (s3) { 11 , 22 , 33 , 44 } |
集合的方法介绍完毕,下面通过一个例子来应用一下set集合的方法:
大家都知道哦CMDB,下面有台服务器4个内存插槽,近期已更换内存,要将新更换的内存信息同步到CMDB里,具体更新信息如下:
1
2
3
4
5
6
7
8
9
10
|
old_mem = { '#1' : 8 , '#2' : 4 , '#4' : 2 , } new_mem = { '#1' : 4 , '#2' : 4 , '#3' : 2 , } |
操作步骤:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
old_set = set (old_mem.keys()) #将新旧字典的key转换成集合 new_set = set (new_mem.keys()) remove_set = old_set.difference(new_set) #找出要删除的信息 add_set = new_set.difference(old_set) #找出要添加的信息 update_set = new_set.intersection(old_set) #取两者交集进行更新 for i in remove_set: #通过循环的方式进行操作 del old_mem[i] #删除旧字典里的老数据 print (old_mem) for i in add_set: old_mem[i] = new_mem[i] # 添加新数据到旧字典 print (old_mem) for i in update_set: old_mem[i] = new_mem[i] #旧字典重新赋值 print (old_mem) { '#2' : 4 , '#1' : 8 } { '#3' : 2 , '#2' : 4 , '#1' : 8 } { '#3' : 2 , '#2' : 4 , '#1' : 4 } |
二、python函数定义
(一),函数定义
首先我们来看定义函数要遵循的规则:
1,函数代码块以def关键词开头,后接函数标识名称和圆括号();
2,任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数;
3, 函数的第一行语句可以选择性地使用文档字符串,用于存放字符串;
4,函数内容以冒号起始,并且缩进
5,return[表达式]结束函数,选择性的返回一个值给调用方,不带表达式的return相当于返回None。
1,语法说明:
1
2
3
4
|
def functionname( parameters ): "函数使用说明" #在pycharm中输入"""回车"""自动生成说明模板 function_suite return [expression] |
2,函数调用
1
2
3
4
5
6
7
8
9
10
11
12
|
def printme( str ): """ :param str: 打印任何传入的字符串 :return: None """ print ( str ) return # 调用函数 printme( "调用函数!" ) 结果:调用函数! |
(二),函数的参数
函数参数的分类:
1、普通参数(严格按照顺序,将实际参数赋值给形式参数)
2、默认参数(必须放置在参数列表的最后)
3、指定参数(将实际参数赋值给制定的形式参数)
4、动态参数:
* 默认将传入的参数,全部放置在元组中, f1(*[1`1,22,33,44])
** 默认将传入的参数,全部放置在字典中 f1(**{"kl":"v1", "k2":"v2"})
5、万能参数, *args,**kwargs
下面逐个介绍函数参数的用法:
首先附上一个发邮件的函数,大家可以玩一玩:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
def sendmail(): import smtplib from email.mime.text import MIMEText from email.utils import formataddr msg = MIMEText( '特斯拉已经到北京,请来4S店取货。' , 'plain' , 'utf-8' ) msg[ 'From' ] = formataddr([ "" , 'dihaifeng@126.com' ]) msg[ 'To' ] = formataddr([ "走人" , '123424324@qq.com' ]) msg[ 'Subject' ] = "主题" server = smtplib.SMTP( "smtp.126.com" , 25 ) server.login( "dihaifeng@126.com" , "sdfsadfsadffadf" ) server.sendmail( 'dihaifeng@126.com' , [ '123424324@qq.com' , ], msg.as_string()) server.quit() sendmail() |
1、普通参数(位置参数)
1
2
3
4
5
6
7
8
9
10
11
|
def send(name,content,status): #括号里面的参数为形式参数 print (name,content,status) print ( '发送成功:' ,name,content) return True while True : email = input ( '请输入邮箱地址:' ) result = send(email, "你好" ,"OK" ) #调用函数传入的是实际参数,参数位置一一对应 if rsult = = True : print ( '发送成功' ) else : print ( '发送失败' ) |
2、默认参数(缺省参数)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
def send(name,content,status = 'Ok' ): print (name,content,status) print ( '发送成功:' ,name,content,status) return True while True : email = input ( '请输入邮箱地址:' ) send(email, '呵呵' ) 结果: 请输入邮箱地址:dihaifeng@ 126.com dihaifeng@ 126.com 你好 Ok 发送成功: dihaifeng@ 126.com 你好 Ok #status为默认参数,在python中默认参数必须放置在参数列表的最后 |
3、指定参数
1
2
3
4
5
6
7
8
9
10
11
12
13
|
def send(name,content,status): print (name,content,status) print ( '发送成功:' ,name,content,status) return True #只要出现return,函数终止 while True : email = input ( '请输入地址:' ) send(name = email,status = 'OK' ,content = '你好' ) #可以指定形式参数的内容(无序的) 结果: 请输入地址:dihaifeng@ 126.com dihaifeng@ 126.com 你好 OK 发送成功: dihaifeng@ 126.com 你好 OK |
4、动态参数(*)
1
2
3
4
5
6
7
8
9
10
11
|
def send( * args): #*号可以接受动态参数 print (args, type (args)) li = [ 11 , 22 , 33 , 'hehe' ] send(li) #直接将列表看成一个元素写到元组中 结果:([ 11 , 22 , 33 , 'hehe' ],) < class 'tuple' > send( * li) #传参的时候加*,代表将上面定义的元素循环写入args元组里 结果: ( 11 , 22 , 33 , 'hehe' ) < class 'tuple' > |
上面有一个问题就是能不能传入字符串,答案是可以的,参数为字符串是,安装字符循环写到元组里。
5、动态参数(**)默认将传入的参数,全部放置在字典中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
def f1( * * args): print (args, type (args)) 方法 1 : f1(k1 = 'v1' ,k2 = 'v2' ) 结果:{ 'k1' : 'v1' , 'k2' : 'v2' } < class 'dict' > 方法 2 : dic = { 'k1' : 'v1' , 'k2' : 'v2' } f1(kk = dic) 结果:{ 'kk' : { 'k1' : 'v1' , 'k2' : 'v2' }} < class 'dict' > 方法 3 : f1( * * dic) 结果:{ 'k1' : 'v1' , 'k2' : 'v2' } < class 'dict' > |
6、万能参数(*args,**kwargs)既可以接收字符串,列表元组也可以接收字典等特殊类型。
1
2
3
4
5
6
|
def f1( * args, * * kwargs): print (args,kwargs) f1( 1 , 2 , 3 , 4 ,k1 = 'v1' ,k2 = 'v2' ) 结果: ( 1 , 2 , 3 , 4 ) { 'k2' : 'v2' , 'k1' : 'v1' } |
(三),函数的特性
函数的特性:
1、根据python代码从上问下的执行顺序,下面的代码第一个f1()函数为无效函数,python会当作垃圾内存就行处理。
1
2
3
4
5
6
7
8
|
def f1(a1,a2): return a1 + a2 def f1(a1,a2): return a1 * a2 ret = f1( 8 , 8 ) print (ret) 64 |
2、Python中传递参数为引用,而不是在内存中申请新的内存
1
2
3
4
5
6
7
|
def f1(a1): a1.append( 999 ) li = [ 11 , 22 , 33 , 44 ] f1(li) print (li) [ 11 , 22 , 33 , 44 , 999 ] |
3、全局变量
1
2
3
4
5
6
7
8
9
10
11
12
|
NAME = [ 11 , 22 , 33 , 44 ] #定义全局变量时字母全部大写 def f1(): age = 18 #全局变量,所有作用域都可读 global NAME #在函数中修改全局变量时,必须声明global就行修改 NAME=[ 5]
print (age,NAME) def f2(): age = 19 print (age,NAME) f1() f2() |
4、lambda: 简单的函数可以使用lambda表达式进行定义,a1,a2为形式参数,可以传入多个数
1
2
3
4
5
6
7
8
9
10
11
12
|
def f1(a1): return a1 + 100 ret = f1( 10 ) print (ret) f2 = lambda a1,a2: a1 + 100 r2 = f2( 102 , 20 ) print (r2) 结果: 110 202 |
下面举两个例子来巩固一下刚才的函数的内容:
1,字符串格式化format()
1
2
3
4
5
6
7
8
9
|
#帮助信息 def format ( self , * args, * * kwargs): # known special case of str.format """ S.format(*args, **kwargs) -> str Return a formatted version of S, using substitutions from args and kwargs. The substitutions are identified by braces ('{' and '}'). """ pass |
1
2
3
4
5
6
7
8
9
|
s1 = 'I am {0}, age {1}' . format ( 'alex' , 18 ) #传入字符串 print (s1) s2 = 'I am {0} age {1}' . format ( * [ 'alex' , 18 ]) #传入列表 print (s2) s1 = 'I am {name}, age {age}' . format (name = 'alex' ,age = 18 ) #传入字典 print (s1) dic = { 'name' : 'alex' , 'age' : 18 } s2 = 'I am {name}, age {age}' . format ( * * dic) print (s2) |
2、一个登录的小程序
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
32
33
34
35
36
37
38
39
40
41
42
|
def login(username,password): """ 定义登录函数 :param username:记录用户传入的user :param password:记录用户传入的passwd :return: 返回值 """ f = open ( 'user' , 'r' ) for line in f: line_list = line.split( '|' ) if line_list[ 0 ] = = username and line_list[ 1 ] = = password: return True return False def register(username,password): """ :param username: :param password: :return: """ f = open ( 'user' , 'a' ) temp = '\n' + username + '|' + password f.write(temp) f.close() def main(): t = input ( '1:登录,2:注册' ).strip() if t = = '1' : user = input ( '请输入用户名:' ) passwd = input ( '请输入密码:' ) r = login(user,passwd) if r: print ( '登录成功' ) else : print ( '登录失败' ) elif t = = '2' : user = input ( '请输入用户名:' ) passwd = input ( '请输入密码:' ) ret = register(user,passwd) main() |