一、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)
结果:110202 |
下面举两个例子来巩固一下刚才的函数的内容:
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() |