Python开发Day03
基本类型的补充:
-
set集合
-
介绍:
- set集合是一个无序且不重复的元素集合,我们可以使用他来对比,去重,查看重复项(交集),不重复项(差集),a有很多元素,b中有几个元素但是元素都和a中元素相同这样可以判断a是不是b的父集,查看两个合并后去掉两个集合中的重复元素。
-
集合元素
- a={1,2,3,4,5,6,7,8,9}
- b={3,4,5,6}
-
方法:
-
判断a集合是不是b集合的父集或是不是子集:
print(a.issuperset(b)) #判断a集合是不是b集合的父集,也就是说b中有的a中都有,使用True或者False返回 print(a.issubset(b)) #判断a集合是不是b集合的子集,也就是说a中有的b中都有,使用True或者False返回 执行结果: True False
- 清空集合:
a.clear() print(a) 执行结果: set()
- 向集合中添加一个元素:
a.add(10) print(a) 执行结果: {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
- 向集合中添加多个元素:
a.update(['a','b','c','d']) print(a) 执行结果: {1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'c', 'd', 'b'}
- 删除a集合中的3元素(这个方法如果集合中不存在这个元素会报错):
a.remove(3) print(a) 执行结果: {1, 2, 4, 5, 6, 7, 8, 9}
- 删除a集合中的8元素(该方法若是集合中没有这个元素不会报错):
a.discard(8) print(a) 执行结果: {1, 2, 3, 4, 5, 6, 7, 9}
- 随机删除一个元素,因为集合是无序的所以它默认是删除最后一个可是最后一个不固定:
a.pop() print(a) 执行结果: {2, 3, 4, 5, 6, 7, 8, 9}
- 输出两个集合中都存在的元素,产生一个新的值,如果需要用变量接收,或者直接查看(交集)。
print(a.intersection(b)) 执行结果: {3, 4, 5, 6}
- 对比两个集合中都存在的元素,修改原来的元素(交集)。
a.intersection_update(b) print(a) 执行结果: {3, 4, 5, 6}
- 判断两个集合中有没交集。
print(a.isdisjoint(b)) 执行结果: False
- 将两个集合合并,可以达到去重的效果(并集),如果需要值需要将执行结果给一个变量它不会修改原来的集合。
print(a.union(b)) 执行结果: {1, 2, 3, 4, 5, 6, 7, 8, 9}
- 拿出集合a中存在的b中不存在的,如果需要值需要将执行结果给一个变量它不会修改原来的集合(差集)。
print(a.difference(b)) 执行结果: {8, 1, 2, 9, 7}
- 拿出集合a中存在的b中不存在的,并修改a集合(差集)。
a.difference_update(b) print(a) 执行结果: {1, 2, 7, 8, 9}
- 在a集合或b集合中,但不会同时出现在二者中(对称差集),如果需要值需要将执行结果给一个变量它不会修改原来的集合。。
print(a.symmetric_difference(b)) 执行结果: {1, 2, 7, 8, 9}
-
在a集合或b集合中,但不会同时出现在二者中(对称差集),直接修改a集合:
a.symmetric_difference_update(b) print(a) 执行结果: {1, 2, 7, 8, 9}
-
-
三目运算(三元运算):
-
介绍:
- 三目运算就是是对简单的条件语句的缩写,让之前需要3-4行的特殊代码写成一行:
- 使用方法:
c=0 name='Wu' if c== 0 else 'Qi' #先做if判断如果c等于0那么name的值就是Wu否则值为Qi print(name) 执行结果: Wu
深浅拷贝:
-
数字和字符串
- 对于数字和字符串而言深浅拷贝、赋值,没有是没意义,因为他们如果相同永远指向同一个内存地址:
a='hello' b='hello' c=1 d=1 print(id(a)) #id()查看变量的内存地址
print(id(b))
print(id(c))
print(id(d)) 执行结果: 1902418750296 1902418750296 1521807152 1521807152
- 对于数字和字符串而言深浅拷贝、赋值,没有是没意义,因为他们如果相同永远指向同一个内存地址:
-
其他基本数据类型的深浅拷贝赋值:
-
-
介绍:
- 赋值就是你创建了一个变量然后有值,又创建一个变量给的值指向的就是你之前创建的变量名。
n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]} n2 = n1 print(id(n1)) #查看n1字典在内存的位置 print(id(n2)) #查看n2字典在内存的位置 print(id(n1['k1'])) #查看n1字典中k1值的内存位置 print(id(n2['k1'])) #查看n2字典中k1值的内存位置 执行结果: 1961536305736 1961536305736 1961536697040 1961536697040
- 赋值就是你创建了一个变量然后有值,又创建一个变量给的值指向的就是你之前创建的变量名。
-
-
浅拷贝:
-
介绍:在内存中只创建第一层数据结构:
-
分析:
import copy #拷贝模块 n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]} n2 =copy.copy(n1) #浅拷贝n1 print(id(n1)) #输出n1在内存的位置 print(id(n2)) #输出n2在内存的位置 print(id(n1['k3'])) #输出n1中列表在内存的位置 print(id(n2['k3'])) #输出n2中列表在内存的位置 执行结果: 2162448251464 2162448682888 2162450147144 2162450147144
-
-
-
深拷贝:
-
介绍:
- 在内存中将所有的数据重新创建一遍,除了字符串和数字使用的还是原来的内存地址,因为Python对他们做了优化。
-
深拷贝的分析:
import copy n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]} n2 = copy.deepcopy(n1) #深拷贝 print(id(n1)) #查看n1字典的内存地址 print(id(n2)) #查看n2字典的内存地址 print(id(n1['k3'])) #查看n1字典中的k3值的内存地址 print(id(n2['k3'])) #查看n2字典中的k3值的内存地址 print(id(n1['k1'])) #查看n1字典中的k1值的内存地址 print(id(n2['k1'])) #查看n2字典中的k1值的内存地址 执行结果: 2398849710664 2398850108872 2398851605768 2398851575624 2188442383056 2188442383056
-
函数:
-
背景:
-
在学习函数之前,我们一直遵循:面向过程编程,就是所谓的从上到下的执行实现功能,有时候会有很多重复的代码我们就需要复制粘贴,这样就会导致我们的开发效率,而且容易出错。
-
函数的使用:假设我们有一个脚本在不断的循环查看服务器的各个状态是否正常如果不正常就会发送邮件但是邮件发送使用面向过程的大方会有很多重复的代码既浪费空间还浪费时间。
while True: if cpu利用率 > 90%: #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 硬盘使用空间 > 90%: #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 内存占用 > 80%: #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接
def 发送邮件(内容) #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 while True: if cpu利用率 > 90%: 发送邮件('CPU报警') if 硬盘使用空间 > 90%: 发送邮件('硬盘报警') if 内存占用 > 80%: 发送邮件('内存报警')
可以看出来上面的两种方法第二种要比第一种重用性和可读性要好很多,这就是面向过程和函数式编程的区别
-
解释:
- 函数式编程:将写好的某些功能代码封装到函数中,以后便不需重复编写,直接调用函数就可以。(函数式编程最重要的是增强代码的重用性和可读性)
- 面向对象:对函数进行分类和封装,让开发者开发的效率“更快更好更强...”
- 面向过程:这个代码从上到下的执行。
-
-
定义和使用
-
函数结构:
def 函数名(参数): ... 函数体 ... 返回值
-
函数的定义主要有以下几点:
- def:表示函数的关键字。
- 函数名:函数的名称,以后根据函数名调用函数。
- 函数体:函数中进行一系列的逻辑计算。
- 参数:为函数体提供数据
- 返回值:当函数执行完毕后,给调用者返回需要的数据。
-
-
返回值
-
解释:
- 函数是一个功能块,该功能到底执行是否成功,需要通过返回值来告知调用者。
-
列如:
def test(): a=0 if a == 0 : return '成功' else: return '失败' print(test()) 执行结果: 成功
-
-
参数
-
解释:
- 参数可以更好、更准确的去执行处理,因为如果没有参数那么就相当于函数被写死了。
-
参数例子
- 如果没有参数将会成为这样,需要写很多函数,调用每一个不同的函数,但是函数内部就是改了一个内容而已,这样就和面向过程变成一样了。
def CPU报警邮件() #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 def 硬盘报警邮件() #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 def 内存报警邮件() #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 while True: if cpu利用率 > 90%: CPU报警邮件() if 硬盘使用空间 > 90%: 硬盘报警邮件() if 内存占用 > 80%: 内存报警邮件()
- 加参数函数,这样我们的可读性变得会很好,而且可以很好的操作。
def 发送邮件(邮件内容) #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 while True: if cpu利用率 > 90%: 发送邮件("CPU报警了。") if 硬盘使用空间 > 90%: 发送邮件("硬盘报警了。") if 内存占用 > 80%: 发送邮件("内存报警了。")
- 如果没有参数将会成为这样,需要写很多函数,调用每一个不同的函数,但是函数内部就是改了一个内容而已,这样就和面向过程变成一样了。
-
函数中三种不同的参数
- 普通参数就和我们上面说的一样,但是他必须是有几个形参就要有多少实参,形参就是函数名后面()里的参数个数,实参就是调用函数时的()里写的内容。
def test(name): #参数name,(形参) return name print(test('Wu')) 执行结果: print(test('Wu')) #执行test函数传参Wu。(实参) 执行结果: Wu
- 默认参数:
def test(name='None'): #默认参数必须在形参后面,也可以理解为写到最后面才可以使用。 return name print(test()) 执行结果: None
- 动态参数一:
def test(*name): return name print(test(1,2,3,4,5,7)) #给test函数传很多数字 执行结果: (1, 2, 3, 4, 5, 7) #输入结果为元组类型的。
- 动态参数二:
def test(**name): return name print(test(name='Wu',age=20)) #给函数test传实参,多个参数,必须是**=**因为这种动态参数会以字典的形式返回 执行结果: {'name': 'Wu', 'age': 20}
- 动态参数一和二可以同时使用:
def test(*args,**kwargs):#python默认提供的动态参数名称*args和**kwargs return args,kwargs print(test(123,123,234,name='Wu',age=20)) 执行结果: ((123, 123, 234), {'age': 20, 'name': 'Wu'})
- 普通参数就和我们上面说的一样,但是他必须是有几个形参就要有多少实参,形参就是函数名后面()里的参数个数,实参就是调用函数时的()里写的内容。
-
-
-
- 向动态参数传元组需要加一个*,字典加两个*。
-
-
练习:
- 简述普通参数、指定参数、默认参数、动态参数的区别。
- 写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数
- 写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5。
- 写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5。
- 写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
- 写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者。
- 写函数,检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
dic = {"k1": "v1v1", "k2": [11,22,33,44]}
PS:字典中的value只能是字符串或列表
- 写函数,利用递归获取斐波那契数列中的第 10 个数,并将该值返回给调用者。
def func(arg1,arg2): if arg1 == 0: print arg1, arg2 arg3 = arg1 + arg2 print arg3 func(arg2, arg3) func(0,1)
-
寻找差异
# 数据库中原有 old_dict = { "#1":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 80 }, "#2":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 80 } "#3":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 80 } } # cmdb 新汇报的数据 new_dict = { "#1":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 800 }, "#3":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 80 } "#4":{ 'hostname':c2, 'cpu_count': 2, 'mem_capicity': 80 } }
提示是否删除:?
提示是否新建:?
提示是否更新:?
注意:无需考虑内部元素是否改变,只要原来存在,新汇报也存在,就是需要更新,凭自己想法去做。
练习解答在另一篇中出现 !