day10作业—(闭包迭代器递归)
补充:一个星号的 打散和聚合
a, b , *c = [1,2, 1,4] print( a , b , *c) #1 2 1 4 print(a, b, c) #1 2 [1, 4] *c , = [1,2,3] print(*c)
1.函数名的使用
函数名可以当做值赋值给变量
def func(): print(1) print(func) # 函数的内存地址 a = func a() func()# 函数名可以当做值赋值给变量
#函数名可以当做元素放到容器里
def func2(): print(2) l1 = [func,func2] print(l1) #函数名可以当做元素放到容器里 l1 = [func(),func2()]#None , None print(l1)
#发现 函数名先调用 计算 prinT(6+7)=打印 13 不是打印 6+7
# 不是从前往后 先计算后面的 后面有值 返回或打印
return aa() # 传的是值 # return aa # 传的是地址
# 楼梯 是 定义 箭头是 调用
def f(): def a(): def b(): def c(): return '传递' return c() return b() return a() print(f())
2.闭包
#1. 一个嵌套函数
#2.在嵌套函数的内部函数使用外部(非全局的变量)
#满足以上两条
判断 不是 None
def wrapper(): a = 10 def inner(): print(a) return inner # 返回的地址 第5步 # inner() print(inner.__closure__)#不是None jius就是闭包
# 普通函数 执行调用完 了就销毁了
#python中 闭包 会进行内存驻留
# money = 10 # 以后不要这么干
#全局里存放 会有污染和不安全的现象
# 面试必问 , 装饰器 ---装饰器的本质就是闭包
# 闭包有个弊端: 会出现内存泄露
money = 10 def wrapper(): money = 10 def inner(num): nonlocal money money += num print(money) return inner wrapper()(100)
关于内存地址(列表和字典哪个寻值快?)
列表 (有序空间)每一个值对应一个 内存地址,但是由于找到了第一个值,然后依次取下面的数时,遍历而省去了查找,所以相对省时间。--》链表
字典 每一个键 对应一个哈希表 然后对着 哈希表去寻找值, 所以每一个都须寻找内存地址 ,所以相对列表链式浪费些时间
1.3 迭代器
'''
可迭代对象 可被for 循环的就是可迭代对象
python 协议: 具有.__init__方法的就是可迭代对象
a = 对象.__iter__#创建一个迭代器
具有a.__iter__a.__next__的就是迭代器
'''
l1 = [1,2,3] print(l1.__iter__) #地址 a = l1.__iter__() #赋值 print(a.__next__()) #打印第一个 print(a.__next__()) print(a.__next__()) #若再打印则报错StopIteration # print(a.__next__())#StopIteration 没了取不到
for 循环
对可迭代的内容 进行一个个遍历 从前到后 就是构成一个标准迭代器
for i in [1,2,3]: print(i)
for 循环的迭代器原理
# 做出 for 的机制 li = [1,2,3] em = li.__iter__() while 1: try: #尝试 print(em.__next__()) except StopIteration: #错误类型 # print('你不能这么干') break
#int str list 工厂模式 把零件往里面一扔 车出来了
# 迭代器特性:
# 惰性机制 : 点一个用一个
# 不能从下向上走
# 一次性的,用完就没了
# 省内存
1.4 递归
递归的最大深度 官方1000 实际993
递归的效率比较低,尾递归的用时 和 for的用时 是一样的,比for慢
递归的应用场景:
在不明确要循环的次数时候,可以用递归
递归操作文件目录
def func(n): n+=1 print(n) if n == 5: return func(n) func(2)