程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

【python基礎】生成式、裝飾器、高階函數

編輯:Python

生成式、裝飾器、高階函數

  • 一、生成式
    • (1)、列表生成式
    • (2)、集合生成式
    • (3)、字典生成式
  • 二、生成器
    • (1)、生成器特點
    • (2)、使用方法
  • 三、閉包
    • (1)、了解時間戳
    • (2)、閉包
  • 四、裝飾器
    • (1)、裝飾器
    • (2)、含參數的裝飾器
    • (3)、多個裝飾器
  • 五、內置高階函數
    • (1)、map函數
    • (2)、reduce函數
    • (3)、filter函數
    • (4)、sorted函數

一、生成式

(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]

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved