学习python-Day17
昨日内容回顾
一、多层装饰器
'语法糖:将紧挨着语法糖的函数名作为参数,传递给@符号后面的函数名。大致效果就是谁靠近,谁就先修饰!'
def outer1(func1):
print('加载outer1')
def inner2(*args, **kwargs)
print('执行inner1')
return func1(*args, **kwargs)
return inner1
def outer2(func2):
print('加载outer2')
def inner2(*args, **kwargs)
print('执行inner2')
return func2(*args, **kwargs)
return inner2
def outer3(func3):
print('加载outer3')
def inner3(*args, **kwargs)
print('执行inner3')
return func3(*args, **kwargs)
return inner3
@outer1
@outer2
@outer3
def index():
print('index!!!')
index()
也可以理解成 index = outer(outer2(outer3(index)))
二、有参装饰器
def outer1(a,b,c):
def outer(func_name):
def inner(*args,**kwargs):
res = func_name(*args,**kwargs)
return res
return inner
return outer
@outer1(1,2,3) # outer(1,2,3) @outer index = outer(index)
def index():
print('from index')
'''
注意:: 最外层outer1形参写成 outer1(*args,**kwargs),写没问题,但是使用的时候会冲突,需要改变*和**后面的变量名,outer1(*a,**k)
专门针对有形参的情况下 :
问题2(掌握): 内层inner函数的形参是否可以改写为下面的方式
def inner(user_id,*args,**kwargs):
func_name(user_id,*args,**kwargs)
可以,因为单独将user_id拿出来,是为了后面单独多次重复使用这个参数。
可以将user_id和name、pwd分开,还有这是被修饰对象所需要的参数。
'''
@outer(1,2,3)
def func(user_id,name,pwd):
pass
三、递归函数
函数直接或间接代用直接。
递归两个要求:1.每次递归都比上次简单,更接近结果。2.最后有明确的结果。
两个特征:
1.递归
2.回溯 return
四、算法之二分法
-
什么是算法?
解决问题的方法 -
二分法
数据是排好序的。 就是取列表中间位置的数,与要查找的数作比较。大则目标数在左半侧,小则目标数在右半侧。然后在各半侧在从中间找的数与目标数做比较。以此类推,逐渐靠近要找的目标数。 -
冒泡
冒泡排序是一种简单的排序算法,它也是一种稳定排序算法。 原理是重复扫描待排序序列,并比较每一对相邻的元素,当该对元素顺序不正确时进行交换。一直重复这个过程,直到没有任何两个相邻元素可以交换,就表明完成了排序。 -
快拍
快速排序算法通过多次比较和交换来实现排序。 1.首先设定一个分界值,通过该分界值将数组分成左右两部分。 2.将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。 3.左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。 -
插入
1.用插入算法时一般将数据分为两组,有序组和无序组,并且将数据的第一个元素默认为有序组,将无序组的元素一个一个按照某种排列方式插入到有序组中。 '''有如下一组数据:1,7,2,6,。我们将这组数据从小到大进行排列''' 2.有序组默认为有序组第一个元素,1 与余下无序组7,2,6 的比较。将有序组最后一个元素和无序组第一个元素比较,如果后者大,则放到有序组后面位置。[1,7],[2,6]如果小,则需要从有序组由右往左比较,让这个较小元素插入有序组合适的位置。[1,2,7],[6]有点像斗地主整理牌的思路。
-
推排
-
桶排
今日学习内容
一、三元表达式
主要就是减少了代码行数
'开始缩短单横的条件语句'
1.获取用户输入的用户名,如果是xz就打印欢迎,否则打印抱歉!
username = input('username>>>:').strip()
if username == 'xz':print('欢迎')
else:print('抱歉!')
'三元表达式:仅限于二选一情况(if...else)并且不建议嵌套使用'
2.编写一个函数,比较两个数的大小,返回大的那个
def my_max(a,b):
# if a >b:
# return a
# else:
# return b
return a if a > b else b
res = my_max(1, 10)
print(res)
3.#都为True,第一返回后面的,第二返回前面的。
print('哈哈' if 0 else '嘿嘿')
print('嚯嚯' if 1 else '哼哼')
'运行结果:
嘿嘿
嚯嚯'
4.
username = input('username>>>:').strip()
if username == 'xz':print('欢迎')
else:print('抱歉')
'上面可以再减少行数!!!!'
print('欢迎') if username == 'xz' else print('抱歉')
5.'三元表达式不适合在嵌套里面使用,会让代码越来复杂'
res = 123 if 10 > 5 else (222 if 0 else (666 if 1 == 2 else 666))
'''
三元表达式语法结构
值1 if 条件 else 值2
如果if后面的条件成立,则使用if前面的值
如果if后面的条件不成立,则使用else后面的值
'''
注意:在python代码中不是越少越好,还要保证代码的可读性!!!
二、各种生成式
-
列表生成式
name_list = ['xz', 'wyb', 'bx', 'yyds'] #给上述列表所有的数据值加上s的后缀 #1.定义一个新的列表 new_list = [] #2.循环将原列表所有的数据值取出来 for name in name_list: #3.将取出的数据值拼接一个 s new_name = name + 's' #再把拼接好的名字再添加到新的列表中 new_list.append(new_name) print(new_list) '运行结果: ['xzs', 'wybs', 'bxs', 'yydss']' '可以将上述的代码弄成 一行代码 的 列表生成式 ' #先执行for循环,然后将一个个的数据值交给for循环前面的拼接处理,最后在整理成一个新列表。 new_list = [name + 's' for name in name_list ] print(new_list) # 先执行for循环,然后后将一个个数据值交给if去判断, 结果为True则最后交给for循环前面的拼接处理。 new_list = [name + 's' for name in name_list if name != 'xz'] print(new_list) '运行结果: ['wybs', 'bxs', 'yydss']' 注意:列表生成式中只能出现for和if!!!!不能再后面添加else,系统没法识别else到底属于哪层。 -
字典生成式
#for循环将i作为K值,然后将每个k值循环到后面的if判断,当i 为6 时为True,将i为6 的k值,xz为v值放到这个字典中。 new_dict = {i: 'xz' for i in range(10) if i == 6} print(new_dict) #{6:'xz'} -
集合生成式
#将i从0 到 10 for循环一个个取出,交给后面if判断,如果i 为6,则将i为6 放到这个集合中。 new_set = {i for i in range(10) if i == 6} print(new_set) -
元组
new_tuple = (i for i in range(10)) print(new_tuple)at 0x000001E62B8ED740> 注意:元组没有所谓的生成式,它是后面重点讲解的迭代器知识(生成器)
三、匿名函数
-
匿名函数就是没有函数名的函数
-
语法结构:
?
lambda 形参 : 返回值? eg:
?
直接调用:(lambda x : x + 1)(123)?
命名调用:res = lambda x : x + 1 -
应用场景:
?
匿名函数通常需要配合其他函数一起使用,用于减少代码。
四、匿名集合内置函数的使用
max() # 求最大值
l1 = [1,2,3,4,5]
res = max(l1)
print(res) # 5
#用内置函数可以快速的求出结果。
dict1 = {
'jason': 100,
'aj': 123,
'Bason': 9999,
'zero': 888
}
#方式一:直接用函数
#传入一个形参K
def index(k):
#得到K值对应的(V)数据值并其返回
return dict1.get(k)
#key相当于将index的返回值拿过来给前面的dict1,这里前面的dict1,相当于 for 循环key里面数据值。
res = max(dict1, key = index)
print(res)
#方式二:用匿名函数
#lambda 后面的K表示形参,冒号后面表示字典按k取值将每个数据值取出,然后返回给 key 每个数据值。然后dict1将每个key 的数据值用for循环取出最大值!!!
res = max(dict1, key = lambda k: dict1.get(k))
print(res)
补充:字符串可以做比较。按字符编码表来比较。
A-Z 65-90
a-z 97-122
五、重要的内置函数
min() #最小值
'方法返回字符串中最小的字母'
map() #映射
'会根据提供的函数对指定序列做映射'
函数语法:
map(function, iterable, ...)
l1 = [11, 22, 33, 44, 55, 66]
# 需求:将列表中所有的数据值自增20
# 方式1:for循环
new_list = []
for i in l1:
i += 10
new_list.append(i)
print(new_list)
# 方式2:列表生成式
new_list = [i+10 for i in l1]
print(new_list)
# 方式3:map函数
res = map(lambda i : i + 10, l1)
print(res) #
filter() #过滤
'函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成新的列表'
l1 = ['xz', 'wyb', 'bx', 'yyds']
# 需求:移除数据值里面的yyds
# 方式1:for循环
for i in l1:
if i == 'yyds':
l1.remove(i)
print(l1)
# 方式2:列表生成式
#可以用刚刚拼接的方式,for循环内有内置方法的话,可以用if判断i是不是'yyds'。
#如果不是,返回为True,将数据值传入for循环前面的i,yigg放入new_list
new_list = [i for i in l1 if i != 'yyds']
print(new_list) #['xz', 'wyb', 'bx']
#方式3:filter()
res = filter(lambda a: a != 'xz', l1)
print(res) #
print(list(res)) #['wyb', 'bx']
def index(a):
return a != 'xz'
res = filter(index, l1)
print(list(res)) #['wyb', 'bx']
reduce()
'函数会对参数序列中元素进行累积。'
'''
函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:
用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。
'''
l2 = [1, 2, 3]
# 需求:求列表中所有数据值的和
# 方式1:for循环
s = 0
for i in l2:
s += i
print(s)
# 方式2:sum()
res = sum(l2)
print(res)
# 方式3:reduce() 将很多单体 变成一个整体
from functools import reduce
#用匿名函数,l2后面是可以添加数据值的。
res = reduce(lambda x, y: x + y, l2, 100)
print(res)
#不用匿名函数,直接就是函数。
def index(x,y):
return x + y
print(res)
zip()
1.函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象,这样做的好处是节约了不少的内存。
2.可以使用 list() 转换来输出列表。
3.如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
eg:
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> a1, a2 = zip(*zip(a,b))
# 与 zip 相反,zip(*) 可理解为解压,返回二维矩阵式
>>> list(a1)
[1, 2, 3]
>>> list(a2)
[4, 5, 6]
#元素根据位置一一对应然后组成一个元组,再用list转化成列表里的元组。
n1 = [1, 2, 3]
n2 = ['xz', 'wyb', 'bx']
res = zip(n1, n2)
print(res) #
print(list(res))
'运行结果:
[(1, 'xz'), (2, 'wyb'), (3, 'bx')]'
#字符串是拆开一个个字符对应。字符串最小单位为一个字符
n1 = [1, 2, 3, 4]
n2 = [5, 6, 7, 8]
n3 = 'wyb'
res = zip(n1, n2, n3)
print(list(res))
'运行结果:
[(1, 5, 'w'), (2, 6, 'y'), (3, 7, 'b')]'
# 元素个数与最短的列表一致
n1 = [1, 2, 3, 4, 5, 6, 7]
n2 = [5, 6, 7, 8]
n3 = 'xz'
res = zip(n1, n2, n3)
print(list(res))
'运行结果:
[(1, 5, 'x'), (2, 6, 'z')]'
作业
一、多层装饰器
首先,我们要从头开始分析代码开始定义的什么东西。要秉持先定义再调用的概念。我们要明白语法糖的含义。找到语法糖。然后将语法糖的原来的样子写出来。打个备注在旁边。