day12 迭代器 生成器 装饰器 递归 -05.13

回顾

  1. 函数就是变量
  • 定义函数就是定义类型是function的变量,函数名就是变量名(变量能做的事函数就能做)
  1. 实参高阶函数 max min sorted map reduct

    max(序列,key = 函数)

    min(序列,key = 函数)

    sorted(序列,key = 函数)

    map(函数,序列)

    map(函数,序列1,序列2)

    from functools import reduce

    reduce(函数,序列,初始值)

总结

迭代器

  1. 迭代器(iter)
  • 迭代器是容器型数据类型(序列),迭代器无法直接获取所有元素,也不能统计元素个数,获取迭代器中元素时,会导致这个元素从迭代器中消失。(元素取一个就少一个)
  1. 创建迭代器
  • 创建迭代器只有两种方式:将其他序列转换成迭代器 创建生成器

    iter1 = iter('sfg')
    print(iter1)  #<str_iterator object at 0x0000020AD885B0C8>
    
    iter2= iter([23,45])
    print(iter2)  #<list_iterator object at 0x000001A6AC59A2C8>
    
  1. 获取迭代器中的元素

    # 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)
    

生成器

  1. 生成器
  • 生成器从获取数据和保存特点来看,就是迭代器
  • 生成器保存数据的本质不是保存数据本身,而是保存产生数据的算法
  1. 创建生成器
  • 调用带有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}')
  1. 确定生成器的元素–生成器可以创建的数据
  • 一个生成器能产生多少个数据就看这个生成器对应的函数,执行完函数会遇见几次yield,每次遇到yield的时候后面的数据就是产生的数据

    def func2():
         yield 139
         yield 44
         yield 24 #这个生成器产生3个数据
    result = func2()
    print(next(result))
    
  1. 生成器产生的原理

    '''当通过生成器对象获取元素(不管以什么方式获取)的时候,系统会自动执行生成器
    对应的函数,执行函数的时候不会直接将整个函数执行完,而且每次在执行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))
    

装饰器

  1. 装饰器(无参)
  • 装饰器= 实参高阶函数+ 返回值高阶函数+糖语法(装饰器本质就是函数)
  1. 创建无参装饰器的方法
'''
装饰器的工作原理:将需要添加功能的函数传给装饰器,装饰器创建一个保留原函数功能
                并且添加新功能的一个新的函数,
                将添加完功能的新函数返回,最后用新函数代替原来的函数

装饰器的套路:
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)))

递归

  1. 递归函数
  • 在定义函数的时候调用函数本身,这种函数就是递归函数

  • 理论上循环能做的事情递归都能做(能用循环做的就不用递归)

  • 注意:使用递归解决循环问题的时候,内存和cpu的消耗会随着循环次数的增加而不断增加

    def fn():
    #     print('hello')
    #     fn()
    #
    # fn()
    
  1. 使用递归的套路

    '''
    第一步:找临界值,在临界值的位置结束函数(相当于循环结束的条件)
    第二步:找关系,找上一次循环结束的结果和当循环结束的结果关系
    第三步:假设函数功能已经实现,通过关系用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)
    

    作业

  2. 为函数写一个装饰器,在函数执行之后输出 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))
    
  3. 为函数写一个装饰器,把函数的返回值 乘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())
    
  4. 写一个装饰器@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>
  1. 写一个创建一副扑克牌的生成器。

    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))
    
  2. 使用递归函数画出以下图形:

    n = 5
    *****
    ****
    ***
    **
    *
    
    
    n = 4
    ****
    ***
    **
    *
    def star(n):
        if n==1:
            print('*')
            return
        print('*'*n)
        star(n - 1)
    star(5)
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值