day12-三大神器

day12-三大神器

一、迭代器

list1 = [19, 89, 78, 67]
result = map(lambda item: item % 10, list1)
print(result)   # 迭代器,打印看不到元素
print(list(result))  # 取出来转换成列表
print(list(result))  # 取出来用了后元素就没有了,不会再放回去

1.什么是迭代器(iter)

迭代器是容器型数据类型(序列),迭代器无法直接获取所有元素,也不能统计元素个数。
获取迭代器中的元素是会导致这个元素从迭代器中消失。(元素取一个就少一个)

2.创建迭代器

创建迭代器只有两种方法:1)将其他序列转换成迭代器 2)创建生成器

iter1 = iter('abc')
print(iter1)   # <str_iterator object at 0x0000000001DF6970>

iter2 = iter([10, 20, 30, 40])
print(iter2)

iter3 = iter([{'a': 10}, {'b': 20}])
print(iter3)

3.获取迭代器中的元素

1)获取单个元素:next(迭代器)

iter1 = iter('abc')
print(next(iter1))   # a
print(next(iter1))   # b
print(next(iter1))   # c
# print(next(iter1))   # StopIteration

iter3 = iter([{'a': 10}, {'b': 20}])
print(next(iter3))    # {'a': 10}
print(next(iter3))    # {'b': 20}

2)遍历

iter2 = iter([10, 20, 30, 40])
for x in iter2:
    print(f'x:{x}')

for x in iter2:
    print(f'x:{x}')  # 空

二、生成器

1.生成器

生成器从获取数据和保存特点来看,就是迭代器。
生成器保存数据的本质不是保存数据本身,而是保存产生数据的算法。

2.创建生成器

调用带有yield关键字的函数就可以得到一个生成器
调用带有yield关键字的函数的时候不会执行函数体,也不会获取函数返回值,只是单纯的创建一个生成器

def func1():
    yield
    print('=====')
    return 100


result = func1()
print(result)

3.确定生成器的元素 - 生成器可以创造的数据

一个生成器能产生多少个数据就看这个生成器对应的函数,执行完函数会遇到几次yield。
每次遇到yield的时候yield后面的数据就是产生的数据

def func2():
    yield 100
    yield 200
    yield 300


result = func2()
print(next(result))  # 100
print(next(result))  # 200
print(next(result))  # 300

4.生成器产生数据的原理

当通过生成器对象获取元素(不管以什么样的方式获取)的时候,系统会自动执行生成器对应的函数,执行函数的时候不会直接将整个函数执行完
而且每次在执行yield的时候就会停下来,并且将yield后面的数据作为结果返回。
下次再获取元素的是从上次结束的位置开始执行

def func3():
    print('11111111')
    yield 100
    print('222222')
    yield 200
    print('3333333')
    yield 300
    print('4444444')


result = func3()
print(next(result))
print('!!!!!!!!!!!!!!!!!')
print(next(result))
print('!!!!!!!!!!!!!!!!!')
print(next(result))

for x in result:
    print(x)


def func4():
    yield print('abc')


result = func4()
print(next(result))  # None


def func4():
    yield 'abc'


result = func4()
print(next(result))


def func5():
    yield 10
    yield 20
    yield 30
    yield 40


print(next(func5()))   # 10
print(next(func5()))   # 10

result = func5()
print(next(result))    # 10
print(next(result))    # 20
# 写一个创建学生学号的生成器,要求产生的学号前缀是python,后面是指定范围的值
# 26 ~ 56  ->python0026 ~ python0056

def s_num(subject='python', start=26, end=56):
    for x in range(start, end+1):
        yield f'{subject}{str(x).zfill(4)}'


result = s_num()
print(next(result))
print(next(result))
for _ in range(3):
    print(next(result))


java = s_num('java', 1, 50)
print(next(java))

三、装饰器(了解)

1.什么是装饰器

装饰器 = 实参高阶函数 + 返回值高阶函数 + 糖语法 (装饰器的本质是函数)
作用:给已经定义好的函数添加功能

import time

def func1():
    start = time.time()
    print('hello world!')
    end = time.time()
    print(f'函数执行时间:{end-start}')


func1()


def func2(a, b):
    start = time.time()
    print(a + b)
    end = time.time()
    print(f'函数执行时间:{end-start}')


func2(10, 9)


def total_time(fn):
    def new_fn(*args, **kwargs):
        start = time.time()
        result = fn(*args, **kwargs)
        end = time.time()
        print(f'函数执行时间:{end-start}')
        return result
    return new_fn


@total_time
def func3():
    print('hello world!')


func3()

2.无参装饰器的实现方法

装饰器的工作原理:将需要添加功能的函数传给装饰器,装饰器创建一个保留原函数功能并且添加新功能的一个新的函数
将添加完功能的新函数返回,最后用新的函数替换原来的函数。

装饰器的套路:
def 函数名1(参数1:function):
def 函数名2(*args, **kwargs):
添加新的功能
result = 参数1(*args, **kwargs)
return result
return 函数2

函数名1 - 装饰器功能对应的名字
参数1 - 类型是function,指向需要添加功能的原函数,习惯命名成:fn
函数名2 - 指向添加完功能的新函数,习惯命名成:new_fn

def 装饰器名(fn):
def new_fn(*args, **kwargs):
新功能
result = fn(*args, **kwargs)
return result
return new_fn

# 1.写一个装饰器在函数调用结束的时候打印‘end'
def add_end_message(fn):
    def new_fn(*args, **kwargs):
        result = fn(*args, **kwargs)
        print('end')
        return result
    return new_fn


# 2.写一个装饰器将原函数的返回值加100
def add_100(fn):
    def new_fn(*args, **kwargs):
        result = fn(*args, **kwargs)
        if type(result) in (int, float):
            return result + 100
        return result
    return new_fn

# @add_end_message
@add_100
def func3(num: int):
    sum1 = 1
    for x in range(1, num+1):
        sum1 *= x
    return sum1


x = func3(4)
print(x)


# 练习:写一个装饰器,将函数的返回值变成字符串
def exchange_str(fn):
    def new_fn(*args, **kwargs):
        result = fn(*args, **kwargs)
        return str(result)
    return new_fn


@exchange_str
def func3(num: int):
    sum1 = 1
    for x in range(1, num+1):
        sum1 *= x
    return sum1


print(type(func3(4)))

@exchange_str
def func4():
    return 'hello world!'


print(func4())

四、递归

1.递归函数

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

理论上,循环能做的事情递归都可以做。(能用循环实现就不要用递归)

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

def fn():
    print('hello')
    fn()

2.使用递归的套路

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

# 1.计算1+2+3+...+100
def sum1(n):
    # 临界值
    if n == 1:
        return 1
    return sum(n-1) + n

    # 关系:sum1(n)和sum1(n-1)
    # sum(n) = sum(n-1) + n


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

# 2.打印下面的图形
"""
n=3
*
**
***

n=4
*
**
***
****
"""


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值