day - 12三大神器

三大神器

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

iter1 = lier('abc')
print(iter1)  # <str_iterator object at 0x000002556C238400>

iter2 = lter([10, 20, 30, 40])  # 列表可以  list
print(lter)

iter3 = lter([{'a': 10}, {'b': 20}])  # 字典也可以 dict
print(iter3)
  1. 获取迭代器中的元素
# 1) 获取单个元素:next(迭代器)
iter1 = iter('abc')

print(next(iter1))  # a
print(next(iter1))  # b
print(next(iter1))  # c
# print(next(iter1))  # StopIteration

# 2) 遍历
iter2 = iter([10, 29, 49, 12])
for x in iter:
	print(f'x:{x}')  # x:10  x:29  x:49  x:12
	
for x in iter: 
	print(f'x:{x}')  # 上面已经取完,打印不出来
生成器
  1. 什么是生成器
"""
生成器从获取数据和保存特点来看,就是迭代器
生成器保存数据的本质并不保存数据本身,而是保存产生数据的算法。
"""
  1. 创建生成器
"""
调用带有yield关键字的函数就可以得到一个生成器
调用带有yield关键字的函数的时候不会执行函数体,也不会获取函数返回值,只是单纯的创建一个生成器
        (函数中yield放在哪儿没有关系)
"""

def func1():
    print('====')
    return 100
	yield
    
result = func1()
print(f'result:{result}, list(result)')
  1. 确定生成器的元素 - 生成器可以创造的数据
"""
一个生成器能产生多少个数据就看这个生成器对应的函数,执行完函数体会遇到几次yield
每次遇到yield的时候yield后面的数据就是产生的数据
"""

def func2():
	print('++++')
	yield 100
	yield 200
	yield 300
	if 2 > 10:
		yield 400
	return
	yield 500
	
result = func2()
print(next(result))   # 100
print(next(result))   # 200
print(next(result))   # 300
# print(next(result))   # StopIteration
  1. 生成器产生数据的原理
"""
当通过生成器对象获取元素(不管以什么样的方式获取)的时候,系统会自动执行生成器对应的函数,执行函数的时候不会直接将整个函数执行完,
而且每次在执行yield的时候就会停下来,并且将yield后面的数据作为结果返回。
下次再获取元素的是从上次结束的位置开始执行。
"""

def func3():
    print('1111111')
    yield 100
    print('22222')
    yield 200
    peint('3333333')
    yield 300
    print('444444')
    
result = func3()
print(next(result))
print('!!!!!!!!!!!!')
print(next(result))
prin('~~~~~~~~~~~~~')
for x in result:
    print(f'x:{x}')
    
def func4():
    print(f'x:{x}')
    
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(func5(result)))  # 10
print(next(func5(result)))	# 20
# 练习:写一个创建学生学号的生成器,要求产生的学号前缀是python,后面是指定范围的值。
# 26 ~ 56 -> python0026 ~ python0056
def nums1(subject='python', start=26, end=56):
    for x in range(start, end+1):
        yield f'{subject},{str(x).zfill(4)}'
 
装饰器
import time
  1. 什么是装饰器
"""
装饰器 = 实参高阶函数 + 返回值高阶函数 + 糖语法  (装饰器的本质是函数)
作用:给已经定义好的函数添加功能
"""


# 给函数添加功能解决办法一: 在需要添加功能的所有函数中添加新功能对应的代码
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(23, 45)

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

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


# func1 = total_time(func1)


func1()
print('==============================')


@total_time
def func2(a, b):
    print(a + b)


func2(10, 20)
  1. 无参装饰器的实现方法
"""
装饰器的工作原理:将需要添加功能的函数传给装饰器,装饰器创建一个保留原函数功能并且添加新功能的一个新的函数,
               将添加完功能的新函数返回,最后用新的函数替换原来的函数。
               
装饰器的套路:
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, **kwarks):
        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      # 相当于:func3 = add_end_message(func3)
@add_100       # 相当于 func3 = add_100(func3)
def func3(num: int):
    sum1 = 1
    for x in range(1, num+1):
        sum1 *= x
    return sum1


# @add_end_message
@add_100
def func4():
    print('你好,世界!')


print('===================1=====================')
x = func3(4)
print(x)
# print(func3(4))

print('===================2=====================')
print(func4())
# 练习: 写一个装饰器,将函数的返回变成字符串
# 100 -> '100'
# None -> 'None'
# False -> 'False'

def to_str(fn):
    def new_fn(*args, **kwargs):
        result = fn(*args, **kwsrga)
        return = result
    return new_fn
递归
  1. 递归函数
# 1.递归函数
# 在定义函数的时候调用函数本身,这种函数就是递归函数
# 理论上,循环能做的事情递归都可以做。(能循环实现就不要用递归)
# 注意:使用递归解决循环问题的时候,内存和cpu的消耗会随着循环次数的增加而不断增加

def fn():
    print('hello')
    fn()
  1. 使用递归的套路
"""
第一步:找临界值,在临界值的位置结束函数
第二步:找关系,找上一次循环结束的结果和当次循环结束的结果的关系(f(n))和f(n-1)的关系)
第三步:假设函数功能已经实现,通过关系用f(n-1)实现f(n)的功能
"""
# 1. 计算1+2+3+...+n
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))


def sum2(n):
    sum1 = 0
    for x in range(101):
        sum1 += 1
    return sum1

print(sum2(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(1))
# 2.打印下面的图形
"""
n = 3
*
**
***

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

def star(n):
    if n == 1:
        print('*')
        return
    
    star(n-1)
    print('*'*n)

作业

  1. 为函数写一个装饰器,在函数执行之后输出 after
def nexus(ff):
    def new_ff(*args, **kwargs):
        result = ff(*args, **kwargs)
        print('after')
        return result
    return new_ff
  1. 为函数写一个装饰器,把函数的返回值 乘2再返回值
def nexus1(ff):
    def new_ff(*args, **kwargs):
        result = ff(*args, **kwargs)
        if type(result) in (int, float):
            return result * 2
        return result
    return new_ff
  1. 写一个装饰器@tag要求满足如下功能:
def tag(ff):
    def new_ff(*args, **kwargs):
        result = ff(*args, *kwargs)
        return f'<p>{result}</p>'
    return new_ff

@tag
def render(text):
    # 执行其他操作
    return text

@tag
def render2():
    return 'abc'

print(render('Hello'))   # 打印出: <p>Hello</p>
print(render2())     # 打印出: <p>abc</p
  1. 写一个创建一副扑克牌的生成器。

  2. 使用递归函数画出以下图形:

# n = 5
# *****
# ****
# ***
# **
# *
#
# n = 4
# ****
# ***
# **
# *
def nums(n):
    if n == 1:
        print('*')
        return
    else:
        print(n * '*')
        return nums(n - 1)


print(nums(5))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值