面向過程和函數式編程

1. 編程範式

編程範型編程範式程序設計法(英語:Programming paradigm),(即模範、典範之意,範型即模php

式、方法),是一類典型的編程風格,是指從事軟件工程的一類典型的風格(能夠對照方法學)。python

如:函數式編程面向過程編程面向對象編程指令式編程等等爲不一樣的編程範型。在編程世界裏更是這樣,編程

各類編程範式在不一樣的場景下都各有優劣,誰好誰壞不能一律而論,下面就讓咱們來一 一解讀它們編程語言

2. 面向過程編程

2.1 介紹

面向過程(Procedure Oriented)是一種以過程爲中心的編程思想,是一種基礎的方法,它考慮的是實際地實現函數式編程

基於該思想編寫程序就比如一條流水線首先分析出解決問題所須要的步驟,而後用函數把這些步驟一步一步實現,函數

使用的時候一個一個依次調用就能夠了設計

好比拿學生早上起來去上學這件事說明面向過程,粗略的能夠將過程擬爲:code

(1) 起牀對象

(2) 穿衣排序

(3) 洗臉刷牙

(4) 去學校

# 第一步,起牀
def get_up():
    print('我起牀了')
    
# 第二步,穿衣
def dress():
    print("穿衣服")
    
# 第三步,洗臉刷牙
def brush_teeth():
    print('刷牙,洗臉')
    
# 第四步,去學校
def go_school():
    print("去學校")
    
    
get_up()
dress()
brush_teeth()
go_school()

這4步就是一步一步地完成,它的順序很重要,你只須要一個一個地實現就好了。而若是是用面向對象的方法的

話,可能就只抽象出一個學生的類,它包括這四個方法,可是具體的順序就不必定按照原來的順序。

2.2 優缺點

[優勢]

複雜問題流程化 , 進而簡單化 , 這也是計算機最本質的工做模式 , 最喜歡的工做模式 , 一步一步的來

[缺點]

擴展性很是差

2.3 應用場景

  • 不是全部的軟件都須要頻繁更迭 : 好比編寫腳本
  • 即使是一個軟件須要頻繁更迭,也不併不表明這個軟件全部的組成部分都須要頻繁迭代

3. 函數式編程

函數式編程(英語:)或稱函數程序設計泛函編程,是一種編程範式

函數式編程並不是用函數編程這麼簡單,而是將將電腦運算視爲函數運算,而且避免使用程序狀態以及易變對象

其中,λ演算(lambda calculus)爲該語言最重要的基礎。並且,λ演算的函數能夠接受函數看成輸入(引數)

和輸出(傳出值)。比起指令式編程,函數式編程更加強調程序執行的結果而非執行的過程,倡導利用若干簡單

的執行單元讓計算結果不斷漸進,逐層推導複雜的運算,而不是設計一個複雜的執行過程。表語言有: Haskell、

Erlang,而python並非一門函數式編程語言,可是仍爲咱們提供了不少函數式編程好的特性,如lambda, map,

reduce, filter

3.1 lambda

對比使用def關鍵字建立的是有名字的函數,使用lambda關鍵字建立則是沒有名字的函數,即匿名函數

語法以下 :

lambda 參數1,參數2 : 返回值

[定義]

lambda x, y: x + y  # lambda自帶一個return
print(lambda x, y: x + y)

[調用]

# 調用匿名函數 : 函數內存地址 + ()
# 方式一:

res = (lambda x, y: x + y)(1, 2)
print(res)

# 方式2:
x = (lambda x, y: x + y)
res1 = x(3, 5)
print(res1)

以上都不是匿名函數的真正調用方式 , 由於匿名函數的精髓就在於沒有名字 , 你這又搞出來一個名字 , 那你幹嗎不

用有名函數 def 關鍵字定義呢?

[應用場景]

匿名函數與有名函數有相同的做用域,可是匿名意味着引用計數爲0,使用一次就釋放,因此匿名函數用於臨時使

用一次的場景,匿名函數一般與其餘函數配合使用

[max函數]

接收一個可迭代對象 , 而後比較 , 返回最大值 , 可設置比較的依據

# 需求:打印出薪資最高的那我的的名字
salary_dic = {'tom': 100, 'alex': 500, 'jack': 200}

res = max(salary_dic)       
# max直接迭代字典,只會把字典的key做爲比較依據,咱們須要把值做爲依據,可指定key的值
def func(k):
    return salary_dic[k]


res = max(salary_dic, key=func)  
# max會把迭代的每個值傳遞給key指定的函數內存地址當作實參,而後經過函數的返回值做爲比較的依據
print(res)     # alex

可是你發現了嗎 , func這個函數 , 只適用於此次比較大小 , 沒有其餘可用的做用了 , 既然只用一次 , 那麼用匿名函

數豈不美哉

# k就是函數的形參,實參在代碼層面你是看不到的,可是執行起來會傳參
res = max(salary_dic, key=lambda k: salary_dic[k])
print(res)

[min函數]

salary_dic = {'tom': 100, 'alex': 500, 'jack': 200}

# max取最大,min取最小
res1 = min(salary_dic, key=lambda k: salary_dic[k])
print(res1)

[stored函數]

sorted 排序,也能夠指定比較依據,默認reserve=False,是從小到大排列,能夠設爲True,從大到小排列

salary_dic = {'tom': 100, 'alex': 500, 'jack': 200}


res2 = sorted(salary_dic, key=lambda k: salary_dic[k])
print(res2)

3.2 map

函數map、filter 、reduce都支持迭代器協議,能夠用來處理可迭代對象

map 映射函數

# 1. 把列表中的人名都追加上_dsb
l = ["tao", 'fang', 'huang']

res = map(lambda name: name + "_dsb", l)  # map會把l的值迭代出來交給前面打的函數,而後返回一個迭代器
print(res, type(res))
for i in res:
    print(i)

print(res.__next__())  # 上面代碼已經把迭代器裏面的值取完了,再取就報錯了

3.3 filter

filter 過濾函數

# 去掉有sb(帥逼)結尾的名字
l2 = ['tao_dsb', 'fang', 'huang']


res2 = filter(lambda name: not name.endswith("sb"), l2)
# filter會迭代l2裏面的值,傳遞給lambda,若是返回值爲true就保留原來的值,不然就過濾掉
print(list(res2))

3.4 reduce

reduce 在python3中已經不是內置函數了,可是在python2中仍是

[不指定初始值]

from functools import reduce

l3 = [1, 2, 3, 4, ]
res3 = reduce(lambda x, y: x + y, l3) 
# 能夠指定初始值,若是不指定,默認從l中取出兩個參數,獲得的返回值做爲下一次的一個參數

print(res3)   # 10

[指定初始值]

res4 = reduce(lambda x, y: x + y, ['a','b','c'],"hello")

print(res4)  # helloabc
相關文章
相關標籤/搜索