回顾
- 函数就是变量
- 定义函数就是定义类型是function的变量,函数名就是变量名(变量能做的事函数就能做)
-
实参高阶函数 max min sorted map reduct
max(序列,key = 函数)
min(序列,key = 函数)
sorted(序列,key = 函数)
map(函数,序列)
map(函数,序列1,序列2)
from functools import reduce
reduce(函数,序列,初始值)
总结
迭代器
- 迭代器(iter)
- 迭代器是容器型数据类型(序列),迭代器无法直接获取所有元素,也不能统计元素个数,获取迭代器中元素时,会导致这个元素从迭代器中消失。(元素取一个就少一个)
- 创建迭代器
-
创建迭代器只有两种方式:将其他序列转换成迭代器 创建生成器
iter1 = iter('sfg') print(iter1) #<str_iterator object at 0x0000020AD885B0C8> iter2= iter([23,45]) print(iter2) #<list_iterator object at 0x000001A6AC59A2C8>
-
获取迭代器中的元素
# 1)获取单个元素:next(迭代器) # ' print(next(iter1)) #s print(next(iter1)) #f print(next(iter1)) #g # print(next(iter1)) # 报错 # 2)遍历 for x in iter2: print(f'x:{x}') #you有值 for x in iter2: # 上面被提取了 没值 print(x)
生成器
- 生成器
- 生成器从获取数据和保存特点来看,就是迭代器
- 生成器保存数据的本质不是保存数据本身,而是保存产生数据的算法
- 创建生成器
- 调用带有yield关键字的函数就可以得到一个生成器
- 调用带有yield关键字的函数的时候不会执行函数体,也不会获取函数的返回值,只是单纯的创建一个生成器(yield在哪没关系)
def func1():
print('====')
return 100
result = func1()
print(result)
def func2():
yield #<generator object func1 at 0x000001EF755305C8>
print('====')
return 100
# 这个result 就是生成器
result = func1() #这个生成器一个数据也没有
print(f'result:{result}')
- 确定生成器的元素–生成器可以创建的数据
-
一个生成器能产生多少个数据就看这个生成器对应的函数,执行完函数会遇见几次yield,每次遇到yield的时候后面的数据就是产生的数据
def func2(): yield 139 yield 44 yield 24 #这个生成器产生3个数据 result = func2() print(next(result))
-
生成器产生的原理
'''当通过生成器对象获取元素(不管以什么方式获取)的时候,系统会自动执行生成器 对应的函数,执行函数的时候不会直接将整个函数执行完,而且每次在执行yield的时候会停下来,并且将yield后面的数据 作为结果返回。 下次再获取元素的是上次结束的位置开始执行。 ''' def func3(): print('11111') yield 12 print('2222') yield 23 print('333') yield 244 print('444') result = func3() print(next(result)) def func4(): yield print('sd') # yieid 返回值是None 不是print 打印值 def func5(): yield 23 yield 34 yield 35 print(next(func5())) #23 print(next(func5()) )#23 # result=func5() print(next(result))#23 print(next(result))#34
练习:写一个创建学生学号的生成器,要求产生的学号前缀是python,后面是指定范围的值。 # 26 ~ 56 -> python0026 ~ python0056 def students( ): for x in range(26,57): yield f'python{str(x).zfill(4)}' # students1 = 'python' + (4 - len(nums))*'0'+ str(nums) result = students() print(next(result)) for _ in range(3): print(next(result))
装饰器
- 装饰器(无参)
- 装饰器= 实参高阶函数+ 返回值高阶函数+糖语法(装饰器本质就是函数)
- 创建无参装饰器的方法
'''
装饰器的工作原理:将需要添加功能的函数传给装饰器,装饰器创建一个保留原函数功能
并且添加新功能的一个新的函数,
将添加完功能的新函数返回,最后用新函数代替原来的函数
装饰器的套路:
def 函数名1(参数1:function):
def 函数2(*args,**kwargs):
添加新的功能
return= 参数1(*args,**kwargs)
return result
return 函数2
def 装饰器名()
函数1 --装饰器功能对应的名字
参数1 -- 类型是function,指向需要添加功能的原函数,习惯命名成:fn
函数名2 -- 指向添加完功能的新函数,习惯命名位:new_fn
def 装饰器名(fn):
def new_fn(*args,**kwargs):
新功能
return = fn(*args,**kwargs) #调用原函数
return result
return new_fn
'''
#练习 执行完语句之后加end
def add_end(fn):
def new_fn(*args,**kwargs):
result = fn(*args,**kwargs)
return 'end'
return new_fn
@add_end
def func1():
return 23
print(func1())
def add_end(fn):
def new_fn(*arge,**kwargs):
result = fn(*arge,**kwargs)
print('end')
return result
return new_fn
@add_end
def func3(num:int):
sum1 = 1
for x in range(1,num+1):
sum1 *= x
return sum1
print(func3(3))
# 练习2# 2.写一个装饰器将原函数的返回值加100
def add_100(fn):
def new_fn(*args,**kwargs):
result = fn(*args,**kwargs)
result = result +100
return result
return new_fn
@add_100
def func2(nums:int):
sum = 0
for x in range(nums):
sum += x
return sum
print(func2(5))
# 练习3 写一个装饰器,将函数的返回值变成字符串
# 100 - > '100'
def add_str(fn):
def new_fn(*arge,**kwargs):
result = fn(*arge, **kwargs)
return str(result)
return new_fn
@add_str
def print1(num):
return num
print(print1(43))
print(repr(print1(43)))
print(type(print1(43)))
递归
- 递归函数
-
在定义函数的时候调用函数本身,这种函数就是递归函数
-
理论上循环能做的事情递归都能做(能用循环做的就不用递归)
-
注意:使用递归解决循环问题的时候,内存和cpu的消耗会随着循环次数的增加而不断增加
def fn(): # print('hello') # fn() # # fn()
-
使用递归的套路
''' 第一步:找临界值,在临界值的位置结束函数(相当于循环结束的条件) 第二步:找关系,找上一次循环结束的结果和当循环结束的结果关系 第三步:假设函数功能已经实现,通过关系用f(n-1)实现fn的功能 ''' # 计算1+2+3+ +100 def sum1(n): # 临界值 if n == 1: return 1 # 关系:sum1(n) 和 sum1(n-1) # sum1(n)= 1+2+3+ +n-1 +n # sum1(n-1) = 1 + 2 + 3 + +n - 1 # sum1(n) = sum1(n-1) + n return sum1(n-1) +n print(sum1(100)) # 1,1,2,3,5,8,13... def num(n): if n == 1 or n==2: return 1 return num(n-1)+num(n-2) print(num(2)) # 2.打印下面的图形 # n= 3 # # * # ** # *** def star(n): if n==1: print('*') return star(n-1) print('*'*n) star(5)
作业
-
为函数写一个装饰器,在函数执行之后输出 after
def add_after(fn): def new_fn(*args,**kwargs): result = fn(*args,**kwargs) print('after') return result return new_fn @add_after def sum1(nums): sum2 = 0 for x in range(nums+1): sum2 += x return sum2 print(sum1(4))
-
为函数写一个装饰器,把函数的返回值 乘2再返回值
def result_squ2(fn): def new_fn(*args,**kwargs): result = fn(*args,**kwargs) result = result * 2 return result return new_fn @result_squ2 def func1(): return 243 print(func1())
-
写一个装饰器@tag要求满足如下功能:
def tag(fn):
def new_fn(*args,**kwargs):
result = fn(*args,**kwargs)
return f'<p>{result}</p>'
return new_fn
@tag
def render(text):
# 执行其他操作
return text
@tag
def render2():
return 'abc'
print(render('Hello')) # 打印出: <p>Hello</p>
print(render2()) # 打印出: <p>abc</p>
-
写一个创建一副扑克牌的生成器。
def creat_cards(): list1 = list(range(2, 11)) + ['J', 'Q', 'K', 'A'] list2 = ['黑桃', '红桃', '方块', '梅花'] for x in list1: for y in list2: yield f'{y}{x}' yield '大王' yield '小王' result = creat_cards() print(next(result)) print(next(result))
-
使用递归函数画出以下图形:
n = 5 ***** **** *** ** * n = 4 **** *** ** * def star(n): if n==1: print('*') return print('*'*n) star(n - 1) star(5)