【python基础】生成式、装饰器、高阶函数

一、生成式

(1)、列表生成式

列表生成式就是一个用来生成列表的特定语法形式的表达式。是Python提供的一种生成列表的简洁形式,可快速生成一个新的list。
1、使用方法

普通的语法格式:[exp for iter_var in iterable]
带过滤功能语法格式: [exp for iter_var in iterable if_exp]
带过滤功能语法格式: [exp for iter_var in iterable if_exp]

2、基本运用
它可以将繁琐的方法1简化为方法2

方法1

import string
import random
codes = []
for count in range (100):                            #循环100次,每次都任意生成4个字符串
    code = "".join(random.sample(string.ascii_letters,4))
    codes.append(code)
print(codes)

#结果
['MIFp', 'zJct', 'KpNB', 'afcS', 'zCnv', 'nzgH', 'IlhR', 'UHJk', ....

方法2

codes = [ "".join(random.sample(string.ascii_letters,4)) for i in range(100)]
print(codes)
#结果
['mnLM', 'LVKe', 'ntlM', 'BjYl', 'KIAt', 'gRBl', 'QiqH', ...

3、练习题
找出1到100里面可以被3整除的数
方法1

nums = []
for num in range(1,100):
    if num % 3 == 0:
        nums.append(num)
print(nums)

方法2
利用公式生成器

nums = [num for num in range(1,100) if num % 3 == 0]
print(nums)

(2)、集合生成式

集合生成公式如下

result = {i**2 for i in range(10)}
print(result)
#结果
{0, 1, 64, 4, 36, 9, 16, 49, 81, 25}

(3)、字典生成式

字典生成式如下

result={i:i**2 for i in range(10)}
print(result)
#结果
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

二、生成器

(1)、生成器特点

在python中一边循环一边计算的机制叫做生成器
在这里插入图片描述
运用场景
在这里插入图片描述

(2)、使用方法

1、生成器的方法
方法1:实现的第一种方法(将生成式改写为生成器即可)

nums = (i**2 for i in range(1000))
print(nums)
#结果
<generator object <genexpr> at 0x0000018FFF234900>

上面的不太方便查看,可以用下面这种方法查看值

nums = (i**2 for i in range(1000))
for num in nums:
print(num)
#结果
0
1
4
9
16
25
36
。。。

方法2:yield关键字

 return:函数遇到return就返回,后面的函数不会执行。
 yield: 遇到yield则停止执行代码,再次调用next方法时,从上次停止的yiled继续执行到下一个yield
def login():
    print('step1')              # step
    yield 1                     #output
    print('step')
    yield 2
    print('step 3')
    yield 3
# 如果函数里面有yield关键字,说明函数的返还值是一个生成器
g = login()
print(next(g))
print(next(g))

三、闭包

(1)、了解时间戳

import time
start_time=time.time()    #从1970.1.1到现在的秒数
time.sleep(2)             #休眠两秒
end_time = time.time()    #从1970.1.1到现在的秒数
print(end_time-start_time)
#结果
2.00744891166687

(2)、闭包

1、函数里面嵌套函数
2、外部函数的返回值是内部函数的引用
3、内部函数可以使用外部函数的变量

import time
def timeit(name):
    def wrapper():
        print('wrapper'+name)
    print('timeit')
    return wrapper
in_fun = timeit(name = 'westos')            in_fun此时相当于wrapper函数
in_fun()                                    相当于同时调用了内部和外部的函数

四、装饰器

(1)、装饰器

1、基本模板

import time
from functools import wraps
def 装饰器名称(f):
    @wraps(f)                            保留被装饰器函数的帮助文档
    def wrapper(*args,**kwargs):
        #这里可以添加执行函数前的事情
        result=f(*args,**kargs)
        #执行函数之后做的事情
        return result                    返还函数给被装饰的函数
    return wrapper()

2、举例

# 装饰器:用于装饰函数的功能
# 在不改变源代码的情况下,去添加额外功能的工具
# 用闭包实现装饰器
import time
def timeit(f):
    def wrapper(x,y):
        start = time.time()
        result= f(x,y)                               #执行的是add(x,y)
        end = time.time()
        print('函数运行的时间为:%.4f'%(end-start))
        return result
    return wrapper

@timeit                                              #装饰糖,这里时间上是将add函数转换为timeit(add())
def add(x,y):
      return x+y

result = add(1,3)
print(result)

3、添加wraps,可以对函数的帮助文档进行分别说明

# 装饰器:用于装饰函数的功能
# 在不改变源代码的情况下,去添加额外功能的工具
# 用闭包实现装饰器
import time
from functools import wraps
def timeit(f):
    """" 计时器的装饰器 """
    @wraps(f)                                      #保留被装饰函数的属性信息和帮助文档
    def wrapper(*args,**kwargs):
        start = time.time()
        result= f()                                #执行的是login()
        end = time.time()
        print('函数运行的时间为:%.4f'%(end-start))
        return result
    return wrapper

@timeit                                           #装饰糖,这里时间上是将add函数转换为timeit(add())
def login():
    """"login的帮助文档"""
    print('login')

print(help(timeit))

(2)、含参数的装饰器

import time
from functools import wraps
def timeit(args='seconds'):
    def desc(f):
        """" 计时器的装饰器 """
        @wraps(f)                                                            保留被装饰函数的属性信息和帮助文档
        def wrapper(*args,**kwargs):
            start = time.time()
            result= f()                                                      执行的是login()
            end = time.time()
            if args =='seconds':
                print(f"函数{f.__name__}运行的时间为{end-start}秒")
            elif args == 'mintues':
                print(f"函数{f.__name__}运行的时间为{(end - start)/60}秒")
            return result
        return wrapper
    return desc

@timeit(args='mintues')                                                      先实现timeit() 它将@执行desc函数,即desc=desc(login)
def login():
    """"login的帮助文档"""
    print('login')

login()

(3)、多个装饰器

注意修饰器的调用顺序是从下到上,先调用第二个装饰器is_permisson,再调用第一个装饰器 is_login,但是最终的结果是从上到下 ,输出一个装饰器的结果,再输出第二个装饰器的结果,最终再执行函数的结果。

from functools import wraps
def is_login(f):
    @wraps(f)
    def wrapper1(*args,**kwargs):
        print('is_login,用户是否登录')
        result=f(*args,**kwargs)
        return result
    return wrapper1


def is_permisson(f):
    @wraps(f)
    def wrapper2(*args,**kwargs):
        print('is_permission,用户是否拥有权限')
        result=f(*args,**kwargs)
        return result
    return wrapper2

@is_login
@is_permisson                        注意修饰器的调用顺序是从下到上,先调用is_permisson,再调用 is_login  
def show_hosts():
    print('显示所有的云主机')
    
show_hosts()

具体调用顺序如下

1、is_permisson模块先调用
show_host=is_permisson(show_hosts)
得到结果show_host=wrapper2

2、is_login模块再被调用
show_hosts = is_login(wrapper2) (因为上一个装饰器使得show_hosts为wrapper2,因此这里传入的函数为wrapper2)
得到结果show_hosts=wrapper1

3、上面两步装饰完毕,进行第三步执行show_hosts函数。
现在show_hosts的函数时wrapper1,因此执行show_hosts函数实际是执行wrapper1函数,输出为:
’is_login,用户是否登录‘
然后执行f(*args,**kwargs),根据步骤2发现传进来的函数是wrapper2,因此执行wrapper2函数,输出为:
‘is_permission,用户是否拥有权限’
最后执行执行f(*args,**kwargs),根据步骤1发现传进来的函数是show_hosts,因此执行show_hosts本身函数,输出为:
‘显示所有的云主机’

五、内置高阶函数

(1)、map函数

同时并行的进行处理

#计算x的2次方
result = map(lambda x:x**2,[1,2,3,4])
print(list(result))
#结果
[1, 4, 9, 16]
result=map(lambda x,y:x+y,[1,2,3],[4,5,6])
print(list(result))
#结果
[5, 7, 9]

(2)、reduce函数

将前者的结果作为后者的输入

# reduce函数
# 计算((2**3)**3)=reduce result
from functools import reduce
result = reduce(lambda x, y: x**y, [2, 3, 3])
print(result)

练习·:计算1×2×。。。100

from functools import reduce
result = reduce(lambda x,y: x * y,list(range(1,100)))      注意一定要转换为列表
print(result)

(3)、filter函数

筛选函数
筛选出偶数

result=filter(lambda x:x % 2==0,[1,2,4,5])
print(list(result))
#结果
# filter函数
result=filter(lambda x:x % 2==0,[1,2,4,5])   
print(list(result))                       输出为列表

(4)、sorted函数

进行数字大小排序,从小到大

result = sorted([1,4,321,2])
print(result)
result = sorted([1,4,321,2],reverse=True)
print(result)
#结果
[321, 4, 2, 1]

根据数字是否为0进行排序
函数里面的规则是将非01的赋予为1,然后根据 0 ,1进行排序,根据排序后进行返还真实值

result = sorted([1,4,0,2],key=lambda x:0 if x==0 else 1)
print(result)
[0, 1, 4, 2]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值