python函數式編程

1.  匿名函數和有名函數  c1.py

# 匿名函數
    # 1.lambda 關鍵字,
    # 2.沒有return;只能爲一個表達式,不能爲代碼塊(例如:a = x+y ,就會報錯)
    # 3.沒有名字,
    # 4.調用時賦值給一個變量,同過該變量來調用
    # 5.由於匿名函數後只能接一個表達式,不能接代碼,有了三元表達式就能實現簡單的if else 的實現了

# 有名函數
def add_num(x,y):
    return x+y
# 匿名函數
f = lambda x,y: x+y

# print(add_num(1,2))
# print(f(1,2))

# 三元表達式
# x,y  x大於y x 否則 y

# 在js 中爲 x > y ? x : y

# 在Python中   條件爲真時返回結果 if 條件判斷 else 條件爲假時返回結果 ('x if x > y else y'這個只是一個表達式,結果需要用一個變量接收一下)
x = 2
y = 3
r = x if x > y else y
print(r)

2.  map  c2.py

# map
    # 接收兩個參數:第一個爲一個函數,第二個是一個序列(可以傳入多個列表)
    # map 結合lambda使用,使某些問題更簡單化了 (例如:下邊的球平方)
    # lambda 傳入變量的個數和map第二個參數的列表個數須相同,內部個數可以不等,但最終結果取最小的個數
    # 不論是map還是lambada都不能提高代碼得運行效率,只能使代碼更加簡潔

# 問題:求一組數的平方
list_x = [1,2,3,4,5,6,7,8]
list_x1 = [1,2,3,4,5,6,7,8]
list_x11 = [1,2,3,4]
# list_y = [1, 4, 9, 16, 25, 36, 49, 64]  銅鼓map獲得的,相當於list_x的每一項的映射

def square(x):
    return x*x

# 思路一:通過for in
# for x in list_x:
#     square(x)

# 思路二:通過map實現
r = map(square,list_x)
print(r)
print(list(r))

# 利用map對其進行簡化
r_lambda = map(lambda x: x*x, list_x)
print(list(r_lambda))

# 傳入多個參數
r_lambda1 = map(lambda x,y: x*x + y, list_x,list_x1)
print(list(r_lambda1))

# 傳入多個參數(內部個數不等,取最少的展示)
r_lambda11 = map(lambda x,y: x*x + y, list_x,list_x11)
print(list(r_lambda11))

3.  reduce  c3.py

from functools import reduce

# reduce 
    # 不是全局的,須要從functools中引入
    # 第三個參數是初始值

# 連續計算,連續調用lambda  
    # (第一次會將x傳爲1,y傳爲2;每次lambda表達式的計算結果作爲下一次的lambda的x參與計算,一直到計算結束)
list_x = [1,2,3,4,5,6,7,8]

r = reduce(lambda x,y: x+y,list_x)

print(r)

# 還可以像這樣傳入兩個,並不只是能計算加法其它別的運算也可
a = (0,0)
ar = reduce(lambda x,y: (x,x*x+y),(1,2))
print(ar)

4.  filter  c4.py


# filter 過濾
    # filter 返回必須能是真和假

list_x = [1,0,1,0,0,1]

r = filter(lambda x: True if x == 1 else False,list_x)
# 簡化寫法
# r = filter(lambda x: x,list_x)
print(r)
print(list(r))

5.  c5.py


# 命令式編程
    # def(函數);if else(條件判斷);for(循環)
    # 用的比較多

# 函數式編程
    # map ,reduce ,filter ,lambda (算子) ,
    # 不太建議全盤使用函數式編程,可以在命令式編程中穿插使用,簡化代碼

6.  裝飾器  c6.py

import time
# 裝飾器

# 打印的時間戳,單位是秒

def say1():
    print('hello1')

def say2():
    print('hello2')

# 對修改時封閉的,對擴展是開放的
# 通過將函數作爲參數傳入一個函數的方式

# 現在這種方式不太好,相當遠新增加了一個函數
# 打印時間這個函數本來就屬於每個函數自己的方法
# 更優雅的方式,就得通過裝飾器來實現了
def print_time(func):
    print(time.time())
    func()

print_time(say1)
print_time(say2)

7.  封裝  c7.py

import time

# @ AOP思想

# 封裝的基本原則:可以定義複雜,調用簡單;不能接受調用複雜  (定義只一遍就好,複雜點沒關係,但調用一定得簡單)

# 通過@語法糖,來實現原來的調用方式不變,將新擴展的功能也能執行

# 多個函數調用一個裝飾器,但每個函數可以接收不同個數的參數
# 關鍵字參數

def decorator(func):
    def wrapper():
        print(time.time())
        func()
    return wrapper
@decorator
def f():
    print('hello')


# 不用裝飾器時,感覺挺麻煩的,先把函數當參數傳入,再用一個變量接收返回的函數,再將這個函數執行
# f1 = decorator(f)
# f1()

# 用了裝飾器,原來的執行代碼不變
f()

def decorator11(func):
    def wrapper11(param):
        print(time.time())
        func(param)
    return wrapper11
@decorator11
def f11(param):
    print('hello ' + param)

# 如果需要傳入一個參數
f11('world')

print('~~~不同個數參數~~~')

# 可以通過 *arg 傳入多個參數
def decorator22(func):
    def wrapper22(*arg,**kw):
        print(time.time())
        func(*arg,**kw)
    return wrapper22
@decorator22
def f21(param):
    print('hello ' + param)
@decorator22
def f22(param1,param2):
    print('hello ' + param1)
    print('hello ' + param2)
@decorator22
def f23(param1,param2,**kw):
    # 不過還是比較推薦使用明確參數;但當不知道有哪些參數使,可以使用這種模糊的方式
    print('hello ' + param1)
    print('hello ' + param2)
    # 這裏print的是kw而不是**kw
    print(kw)


f21('world')
f22('你好','you')
f23('sky','sun',a=1,b='flower',c='tree',d='air')

(備註:以上內容來自七月老師的學習筆記,僅作爲學習使用)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章