Python Day 15 递归、匿名函数、内置函数

时间:2022-11-01 19:12:31

  阅读目录

    内容回顾

    生成器的send方法

    递归

    匿名函数

    内置函数

  ##内容回顾

 

#1.带参装饰器 - 自定义 | wraps

def wrap(info)
    def outer1(func):
        from functools import wraps
        @wraps(func)
        def inner(*args, **kwargs):
            # 需要外界的参数
            return func(*args, **kwargs)
        return inner
    def outer2(func):
        def inner(*args, **kwargs):
            # 需要外界的参数
            return func(*args, **kwargs)
        return inner
    if info == '1':
        return outer1
    return outer2
    
# outer = wrap('1')
# @outer
@wrap('1')
def fn():pass


#2.可迭代对象:有__iter__()方法的对象,并且调用__iter__()方法得到迭代器对象

#3.迭代器对象:有__next__()方法的对象,并且调用__next__()方法从前往后逐一取值
# 不依赖索引取值,但必须从前往后依次取值(无法获取索引,也无法计算长度)

#4.for循环迭代器
1)得到操作对象的迭代器对象
2)通过__next__()进行取值
3)自动处理StopIteration异常,结束循环

#5.枚举对象:为被迭代的对象添加迭代索引

#6.生成器:语法同函数,内部包含yield关键字,函数名() 不是函数调用,而是得到生成器对象 -> 就是自定义的迭代器对象


with open('abc.txt', 'r', encode='utf-8') as f:
    for line in f:
        pass
    
def fn():
    # ...
    yield 1
    # ...
    yield 2
obj = fn()
res = next(obj) # 1
fn().__next__() # 1
fn().__next__() # 1
fn().__next__() # 1

  ##生成器的send方法

# send的工作原理
# 1.send发生信息给当前停止的yield,所以在send之前就可以发送个send(None)值,或者使用next(obj)方法
# 2.再去调用__next__()方法,生成器接着往下指向,返回下一个yield值并停止

# 案例:
persons = ['张三', '李四', '王五', '赵六', '钱七']

def order(persons):
    for i in range(len(persons)):
        if i == 0:
            print('%s在面试' % persons[0])
        else:
            print('%s叫%s在面试' % (name, persons[i]))
        print('%s面试完毕' % persons[i])
        name = yield persons[i]

obj = order(persons)
for i in range(len(persons)):
    if i == 0:
        p = obj.__next__()
    else:
        p = obj.send(p)
    print('=============================')

  ##递归

# 递归:
# 函数直接或间接调用本身,都称之为递归
# 回溯:找寻答案的过程
# 递推:推出结果的过程

# 前提条件:
# 1.递归必须有出口
# 2.递归回溯递推的条件一定有规律


# 案例一:获得第 count 个人的年纪
def get_age(count):
    if count == 1:
        return 58
    # 第 九...一 个人 - 2
    age = get_age(count - 1) - 2
    return age

age = get_age(3)
print(age)


# 案例二:求n的阶乘  5! = 5 * 4 * 3 * 2 * 1 = 120
# 5! = 5 * 4!
# 4! = 4 * 3!
# 3! = 3 * 2!
# 2! = 2 * 1!
# 1! = 1
def jiecheng(n):
    if n == 1 or n == 0:
        return 1
    ji = n * jiecheng(n - 1)
    return ji
res = jiecheng(5)
print(res)

  ##匿名函数

def fn(*args, **kwargs):
    # 函数体
    return '返回值'

# 匿名函数:
# 1.匿名函数没有函数名
# 2.匿名函数的关键字采用lambda
# 3.关键字 lambda 与标识函数功能体 : 之间一定是参数,所以省略()
# 4.匿名还是没有函数体,只有返回值,所以函数体和返回值的return关键字都省略了

lambda *args, **kwargs: '返回值'

# 注意:
# 1.参数的使用和有名函数一样,六种形参都支持
# 2.返回值必须明确成一个值,可以为单个值对象,也可以为一个容器对象
# 3.用变量接收,该变量就存放了匿名函数的函数地址
#       -- 函数又有名字了,用完也不能被回收了,匿名函数匿名也没意义了
a = lambda *args, **kwargs: '返回值1', '返回值2' print(a) # (<function <lambda> at 0x0000022D0B7E88C8>, '返回值2') # 返回值1 print(a[0]()) # 正确返回两个值: 主动构成成容器类型 lambda *args, **kwargs: ('返回值1', '返回值2')

  ##内置函数

#max和min内置函数
# max结合内置函数来使用
# max:工作原理
# 1.max内部会遍历iter,将遍历结果一一传给lambda的参数x
# 2.依据lambda的返回值作为比较条件,得到最大条件下的那个遍历值
# 3.对外返回最大的遍历值
max(iter, lambda x: x)


# min工作原理一样,得到的是最小值

#示例:
print(max(10, 2000, 300, 5))
print(max('azbd'))

dic = {
    'owen': (1, 88888),
    'zero': (2, 66666),
    'tom': (3, 77777),
}

def fn(k):
    print(k)
    # return k
    # return dic[k][0]
    return dic[k][1]
res = max(dic, key=fn)
print('====================')
print(res)

def max(iter, fn)
    for v in iter:
        res = fn(v)
        # 用res作为比较对象
    return 用fn提供的返回值作为比较对象,得到最大的v


# max结合匿名函数
dic = {
    'owen': (1, 88888),
    'zero': (2, 66666),
    'tom': (3, 77777),
}
print(max(dic, key=lambda k: dic[k][1]))  # 求薪资最大的人
print(max(dic, key=lambda k: dic[k][0]))  # 求员工号最大的人
print(max(dic, key=lambda k: k))  # 求名字最大
print('=====================')
# min
print(min(dic, key=lambda k: dic[k][1]))  # 求薪资最小的人
print(min(dic, key=lambda k: dic[k][0]))  # 求员工号最小的人
print(min(dic, key=lambda k: k))  # 求名字最小

 

# map:映射
# def fn(x):
#     return x * 2
# res = map(fn, [3, 1, 4, 2, 5])
# print(list(res))

dic = {
    'owen': 3,
    'zero': 5
}
res = map(lambda k: (k, dic[k] * 2), dic)
print(list(res))  # [('owen', 6), ('zero', 10)]
# for v in res:
#     print(v)



# reduce:合并
from functools import reduce
res = reduce(lambda x, y: x + y, [3, 1, 2, 4, 5])  # 所以元素的和
print(res)

res = reduce(lambda x, y: x * y, [3, 1, 2, 4, 5])  # 所有元素的积
print(res)


print(sum([3, 1, 2, 4, 5]))

 

# 1.与类型相关的
# list() str() ord() chr() bool() int() ...

print(ord('A'))
print(chr(97))

# 2.进制转化
print(bin(10))  # 1010
print(oct(10))  # 12
print(hex(10))  # a

print(0b1111)  # 15
print(0o10)  # 8
print(0x11)  # 17
from functools import reduce

# 3.常用操作类的
# range() len() iter() next() enumerate() id() type() print() input() open()

# 4.原义字符串
print(r'a\nb')
print(ascii('a\nb'))
print(repr('a\nb'))


# 5.数学相关运算
# abs() sum() max() min() pow() sorted()
print(abs(-1))
print(pow(2, 3))  # 2**3
print(pow(2, 3, 3))  # 2**3%3

dic = {
    'owen': (1, 88888),
    'zero': (2, 66666),
    'tom': (3, 77777),
}
res = sorted(dic, key=lambda k: dic[k][1])
print(res)  # ['zero', 'tom', 'owen']

res = sorted(dic, key=lambda k: dic[k][1], reverse=True)
print(res)  # ['owen', 'tom', 'zero']


# 6.获取帮助
# help(dict)

# 7.执行字符串: eval() exec()

# 8.反射:getattr() setattr() delattr() hasattr()

# 9.面向对象的装饰器:classmethod() staticmethod()

# 10.面向对象的其他:super() globals() locals()
print(globals())

def fn():
    a = 10
    b = 20
    def inner(): pass
    print(globals())
    print(locals())

fn()