ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

匿名函数

2022-07-07 17:36:36  阅读:170  来源: 互联网

标签:index jason 函数 res 列表 匿名 print


  今日内容

  • 三元表达式
  • 各种的生成式
  • 匿名函数
  • 匿名函数与内置函数的使用
  • 重要内置函数

三元表达式

三元表达式就是一种可以简便写法的语法

比如编写一个函数判断两个数的大小把大的值返回出来

def my_max1(a, b):
    if a > b:
        return a
    else:
        return b
res = my_max(10, 50)
print(res)  # 50 可以得出两个数的较大值

def my_max2(a, b):
    return a if a > b else b
res = my_max2(60, 20)
print(res)  # 60 这样的编写代码也是能够得出两个的较大值
'''但是这样编写明显简单 并且对于代码的行数也有减少'''

# 或则是判断用户登入
username = input('username>>>:').strip()
password = input('password>>>:').strip()
if username == 'jason' and password == '123':
    print('登入成功')
else:
    print('用户名或密码错误')
# 向上述的编写我们也可以编写成三元表达式
username = input('username>>>:').strip()
password = input('password>>>:').strip()
print('登入成功') if username == 'jason' and password == '123' else print('用户名或密码错误')
'''
向上述所编写的代码就是三元表达式
'''
# 三元表达式的语法结构为:
数据值1 if 条件 else 数据值2
'''
但是尽量不要嵌套三元表达式
因为嵌套会让代码可读性变差 不美观
'''

各种生成式

生成式其实也是我们编写代码的时候可以简化代码的一个操作

'''   列表生成式   '''
# 现在要把一个列表中的所有值加10并且放到两一个列表中
l1 = [1, 9, 32, 55, 66, 75]
# 我们首先可以想到要用for循环
new_list = []
for i in l1:
    j = i + 10
    new_list.append(j)
print(new_list)  # [11, 19, 42, 65, 76, 85]
# 我们现在可以用列表生成式来快速的编写
new_list = [i + 10 for i in l1]
print(new_list)  # [11, 19, 42, 65, 76, 85]
'''
两种方式都可以操作 但是列表生成式相对来说会简便许多代码的行数也会减少很多
上面的列表生成式可以理解为:
先执行for循环 然后把列表l1中的数据值一个一个取出来 然后再给前面的 i+10操作 
然后在一个一个放到列表中
'''

# 现在有一个列表现在要把列表中的值在末尾添加一个_nb 并且放到另一个列表中
l1 = ['jason', 'tony', 'kevin', 'jerry', 'oscar']
# 我们可以使用for循环
name_list = []
for name in l1:
    new_name = name + '_nb'
    name_list.append(new_name)
print(name_list)  # ['jason_nb', 'tony_nb', 'kevin_nb', 'jerry_nb', 'oscar_nb']
# 使用for循环是可以做到的 不过我们可以使用列表生成式可以是代码行数减少更简便
new_list = [name + '_nb' for name in l1]
print(new_list)  # ['jason_nb', 'tony_nb', 'kevin_nb', 'jerry_nb', 'oscar_nb']
'''
这样的话我们使用列表生成式会简便许多 代码可读性也可以
其实上面的列表生成式跟最上面的执行过程是一样的
首先执行for循环然后一个一个循环取出来 然后交给前面的表达式操作
最后在一个一个放到列表中
'''
l1 = ['jason', 'tony', 'kevin', 'jerry', 'oscar']
# 现在我们把列表除了jason其他都加上_nb
# 我们也可以直接使用列表生成式
new_list = [name + '_nb' for name in l1 if name != 'jason']
print(new_list)  # ['tony_nb', 'kevin_nb', 'jerry_nb', 'oscar_nb']
'''
这样使用列表生成式时可以很快的使用出来 不需要在使用for循环了
这个表达式的执行过程是
还是先执行for循环 把名字一个一个循环出来 然后交给if判断条件是否成立
如果成立就放到for循环前面的表达式继续操作 
然后在一个一个放到列表中
'''
'''
其实之前两个的代码的列表生成式 都有一个if判断的只不过是 if true 所以就简写了
列表生成式中只能出现 for 与 if 不能出现其他关键字
'''
'''   字典生成式   '''
# 其实字典生成式跟列表生成式差不多 就是字典需要两个参数 一个k一个v
user_dict = {i: 'jason' for i in range(6)}
print(user_dict)  # {0: 'jason', 1: 'jason', 2: 'jason', 3: 'jason', 4: 'jason', 5: 'jason'}
# 字典生成式的表达式也相当于快速生成一个字典 也可以加if判断
user_dict = {i: 'jason' for i in range(6) if i != 3}
print(user_dict)  # {0: 'jason', 1: 'jason', 2: 'jason', 4: 'jason', 5: 'jason'}
'''
其实就是首先for循环然后循环出来的值交给if判断 如果条件成立才会执行for循环前面的表达式
'''
'''   集合生成式   '''
# 集合生成式也跟列表差不多
set1 = {i for i in range(10)}
print(set1)  # {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
# 也是能够快速生成一个集合 也能够加判断
'''
new_tuple = (i for i in range(10))
print(new_tuple)  <generator object <genexpr> at 0x000001E62B8ED740>

而在python解释器中是没有元祖生成器的 元祖特性不能通过这种生成器生成
生成的是一个迭代器
'''

 

 

匿名函数

匿名函数 顾名思义就是没有名字的函数

匿名函数的语法结构:

  lambda 形参: 返回值
lambda是关键字
形参跟有名函数一样可以传多个参数
返回值也跟有名函数一样写啥返回啥
(lambda x: x + 1)(10)  # 直接调用
res = (lambda x: x + 1)(10)
print(res)  # 命名调用

但是如果命名调用的话 就失去了匿名函数的独有风格了 如果要这样调用还不如直接命名一个函数

所以一般匿名函数都是跟一些内置函数来搭配使用的

匿名函数搭配内置函数

# 首先简绍一个函数 max() 这是python解释器的内置函数 它的功能就是计算一个列表中最大的值
l1 = [1, 12, 55, 66, 420, 452, 365, 214, 665, 668, 62, 745, 985, 125, 66, 2236, 225, 4222, 45]
res = max(l1)
print(res)  # 4222 可以计算一个列表中最大值
'''
其实就是for循环一个一个提取出来然后两两比较 大的留下 
然后在跟下一个比较始终都是两两比较 直到取完所有的值
'''
# 现在要计算出一个字典中那个人的薪资是最高的?
dic = {
    'jason': 1213,
    'alex': 4230,
    'egon': 999999,
    'Bean': 12143,
    'zone': 88
}
res = max(dic)
print(res)  # zone
'''
它会打印zone 因为max其实就是先for循环 但是字典参与for循环的只有k
而dic这个字典的k只有字符串而比较字符串的大小是一个一个比较的 如果是因为是根据
英文对应的ASCII表来做比较的 而因为小写z是最大的所以会打印zone 
而如何提取v做比较呢? 这就需要匿名函数了
'''
dic = {
    'jason': 1213,
    'alex': 4230,
    'egon': 999999,
    'Bean': 12143,
    'zone': 88
}
res = max(dic, key=lambda k: dic.get(k))
print(res)  # egon
'''
现在就可以打印最正确的值了
max函数时可以传key的 key后面可以传一个函数名
首先max的底层就是一个for循环 每次for循环出来的值交给函数去处理
但是被循环的数据类型是字典所以 每次循环都是循环字典的k 
max会把循环出来的k 交给后面的函数处理 而后面的函数的功能是
传一个参数 然后通过get方法提取这个参数的值 
比如传进去一个'jason'然后通过函数lambda的返回值dic.get(k)取出v1213
然后在循环下一个然后在两两继续比较 留大的跟下一个继续比较 直到取完
然后把最大的值按照当初for循环的值返回回去
'''
# 我们也可以编写一个有名函数传进去 只不过代码的函数会多出来 利用匿名函数会简便许多 其实用哪个都一样
def func(k):
    return dic.get(k)
dic = {
    'jason': 1213,
    'alex': 4230,
    'egon': 999999,
    'Bean': 12143,
    'zone': 88
}
res = max(dic, key=func)
print(res)  # egon

 

 

 

 

重要的内置函数

min() 函数其实跟max()函数是一样的 只不过是求最小值而已

map

# map : 映射
'''
现在有个需求就是将列表中所有的值都自增10
我们可以用到for循环 列表生成式
现在有个内置函数也可以解决这个需求那就是map
'''
l1 = [1, 2, 3, 4, 5, 6]
res = map(lambda x: x + 20, l1)
print(list(res))  # [21, 22, 23, 24, 25, 26]
def index(x):
    return x + 20
res = map(index, l1)
print(list(res))  # [21, 22, 23, 24, 25, 26]
'''
map其实也是通过for循环一个一个取出列表中的值 
然后交给前面的函数处理 而前面的函数 是传进去一个参数然后返回一个 x+20
就会把传进去的数自增20 然后保存起来 然后在将第二个数传进去再自增20 
然后在保存到前面的数字后面 顺序就会一一对应 直到把列表中的值取完在返回出去
只不过是返回的是一个迭代器 所以在通过列表转换即可
同样的我们也可以吧匿名函数换成有名函数
'''

filter

''' filter '''
# 现在把列表中指定的值给去除 把'jason'去除掉
# 可以用for循环了、列表生成器现在可以用函数filter配合匿名函数

l1 = ['jason', 'tony', 'kevin', 'jerry', 'oscar', 'egon']
res = filter(lambda x: x != 'jason', l1)
print(list(res))  # ['tony', 'kevin', 'jerry', 'oscar', 'egon']

def func(a):
    return a != 'jason'
res = filter(func, l1)
print(list(res))  # ['tony', 'kevin', 'jerry', 'oscar', 'egon']

'''
filter其实也是通过for循环一个一个取出数据值 然后把数据值交给函数去处理
首先通过函数取出列表中的值 然后交给匿名函数lambda 匿名函数的返回值是 x != 'jason'
所以就可以除了'jason'的数据值保存起来 直到列表中的值被取完为止 返回出去
只不过filter返回的也是一个迭代器 需要通过列表转换
函数可以是匿名函数也可以是有名函数
'''

reduce

''' reduce '''
# 它可以将很多单体变成整体
# 现在需要取出列表的总数
'''
可以使用for循环、列表生成式、sum函数
现在还有一个reduce只不过reduce不能直接使用
需要通过模块导入
'''
# from functools import reduce

# l1 = [1, 2, 3, 4, 5]
# res = reduce(lambda x, y: x + y, l1)
# print(res)  # 15
# 我们还可以在reduce末尾在添加一个参数
# res1 = reduce(lambda x, y: x + y, l1, 100)
# print(res1)  # 115
# def func(x, y):
#     return x + y
# res2 = reduce(func, l1, 100)
# print(res2)  # 115
'''
reduce也是一个for循环一个一个取出所有值 然后交给函数处理
reduce会取出两个数据值然后 交个匿名函数匿名函数会返回两个数的和
然后reduce会在取出一个数据值再跟之前的和一起在给函数处理再返回这两个数的和
直到列表中的数据被取完 在返回出去 同样的函数可以是匿名函数也可以是有名函数
'''

zip

''' zip '''
# 将两个列表中的值一一对应组织成列表套元祖
# l1 = [1, 2, 3]
# l2 = ['tony', 'jason', 'egon']
# res = zip(l1, l2)  # 返回的是一个迭代器
# print(list(res))  # [(1, 'tony'), (2, 'jason'), (3, 'egon')]

l1 = [1, 2, 3]
l2 = ['jason', 'tony', 'kevin']
l3 = [4, 5, 6]
res = zip(l1, l2, l3)
print(list(res))  # [(1, 'jason', 4), (2, 'tony', 5), (3, 'kevin', 6)]
# zip可以多个列表一起

l1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
l2 = ['jason', 'kevin', 'tony', 'jerry']
l3 = 'jason'
res = zip(l1, l2, l3)
print(list(res))  # [(1, 'jason', 'j'), (2, 'kevin', 'a'), (3, 'tony', 's'), (4, 'jerry', 'o')]
# 如果其中一个列表的数据值跟其他的列表得值数量不一样那么就会把多的数据除去
# 必须要支持for循环的才行

 

 

作业

1.多层装饰器

def outter1(func1):
    print('加载了outter1')
    def wrapper1(*args, **kwargs):
        print('执行了wrapper1')
        res1 = func1(*args, **kwargs)
        return res1
    return wrapper1

def outter2(func2):
    print('加载了outter2')
    def wrapper2(*args, **kwargs):
        print('执行了wrapper2')
        res2 = func2(*args, **kwargs)
        return res2
    return wrapper2

def outter3(func3):
    print('加载了outter3')
    def wrapper3(*args, **kwargs):
        print('执行了wrapper3')
        res3 = func3(*args, **kwargs)
        return res3
    return wrapper3


@outter1
@outter2
@outter3
def index():
    print('from index')
index()

'''
@outter1:
可以看成是wrapper2当做参数传入 index = outter1(wrapper2)  所以func1就是wrapper2
执行outter1时返回的是wrapper1的内存地址 index现在的内存地址变成了wrapper1   index 就相当于wrapper1
@outter2:
可以看成是wrapper3当做参数传入 index = outter2(wrapper3) 所以func2就是wrapper3
执行outter2时返回的是wrapper2的内存地址  index现在的内存地址变成了wrapper2 所以可以把上面的赋值看成
wrapper2 = outter2(wrapper3)
@outter3:
就是把index当做参数传入 idnex = outter(被装饰对象函数名:index)  所以func3就是index
执行outter3函数的时候返回的是wrapper3的内存地址所以index现在绑定的是wrapper3
wrapper3 = outter(index)
'''
'''
所以运行函数index时因为现在index的内存地址为wrapper1所以会先执行wrapper1()函数
然后运行到res1 = func1(*args, **kwargs)因为现在func1的内存地址为wrapper2 所以会执行wrapper2()函数
因为wrapper2中的func2的内存地址为wrapper3 所以会先执行wrapper3()函数
因为wrapper3中的func3的内存地址为index所以执行index()函数执行完并结束
index()函数结束运行时然后就会结束wrapper3函数然后依次往上结束
'''
'''
所以执行结果为:
加载了outter3
加载了outter2
加载了outter1
执行了wrapper1
执行了wrapper2
执行了wrapper3
from index
'''

2.有参装饰器

 

def outter(choice):
    def login_auth(func_name):
        def inner(*args, **kwargs):
            username = input('username>>>:').strip()
            password = input('password>>>:').strip()
            if choice == '列表':
                print('基于列表验证')
                res = func_name(*args, **kwargs)
                return res
            elif choice == '字典':
                print('基于字典验证')
                res = func_name(*args, **kwargs)
                return res
            elif choice == '文件':
                print('基于文件验证')
                res = func_name(*args, **kwargs)
                return res
            else:
                print('用户权限不够 无法调用函数')
        return inner
    return login_auth

@ outter('列表')    # index = login_auth(index)
def index():
    pass
index()

'''
首先会执行语法糖的outter('列表')函数 因为函数名加括号的优先级是最高的所以要先执行outter()函数
而outter函数里只有两行代码定义了login_auth函数 然后再返回login_auth函数地址 
这样语法糖就会从@outter('列表')变成 @login_auth
@login_auth通过语法糖语法 就会把语法糖下面一行的函数名传入然后赋值 所以func_name就等于index
就等于 index = login_auth(index) 然后执行login_auth函数 
而login_auth函数只有两行代码一个是定义了inner函数 然后返回inner函数的内存地址 
所以现在index就是inner的内存地址 login_auth遇到return结束运行 然后就会执行index函数
执行index函数就是在执行inner函数 当条件成立时就会执行  res = func_name(*args, **kwargs)
而现在func_name 等于index所以就是在执行真正的index函数执行完之后 inner函数就会结束
相当于装饰器整体结束
'''

 

标签:index,jason,函数,res,列表,匿名,print
来源: https://www.cnblogs.com/stephenwzh/p/16455503.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有