'沒有學不會的python--函數式編程以及高階函數'

Python 泛函編程 文章 面向對象程序編程 小藝的代碼 2019-07-19
"

沒有學不會的python


函數式編程

到現在為止,我們的沒有學不會python系列文章已經講了很多知識點了,如果是第一次刷到這篇文章的朋友可以去我主頁看一下以前寫的文章。前面講了很多知識點,每個知識點都輔以代碼作為理解和練手,這些例子都是用面向過程思想編寫的,面向過程的本質就是將一個個複雜問題拆解成簡單問題,意思就是將一個以實現某目的的程序劃分成一個個函數的意思,這就是面向過程的編程思想。

而函數式編程,雖然也是面向過程的一種編程思想,但它又跟一般的面向過程寫法有些不一樣,簡單說就是它更抽象更簡潔,而帶來的副作用就是,代碼比較難懂,執行效率也相對低一點。因此面向對象編程思想可分為兩種,一種是函數式編程另外一種是命令式編程,它們的區別是:

函數式編程關心數據的映射,命令式編程關心解決問題的步驟。翻譯成人話就是,函數式編程只負責處理數據的加工運算,不管代碼邏輯結構,是一種更加抽象的方法。命令式編程就關注於代碼邏輯結構,有時為了使代碼結構更合理更易懂,我們不介意用非常臃腫的寫法去完成一個運算目的。

python作為一門高級語言,自然也支持函數式編程,因為在python中一切皆是對象。可能有些朋友不知道對象是什麼意思,前面講過的那些變量就是對象,對象就是一個個在內存中擁有地址的變量。而函數,也是一種變量,在python中,由於函數也可以作為變量進行傳遞,所以python也支持函數式編程。

函數也是一個對象

要怎麼理解函數也是一個對象呢,最好的辦法就是通過代碼認識一下。

def str_to_int(str_list):
"""
將字符類型的數字轉換成整型
:param str_list:
:return:
"""
result = []
for item in str_list:
result.append(int(item))
return result
def get_total(str_to_int_func, list_1):
"""
對list_1求和
:param str_to_int:
:param list_1:
:return:
"""
parse_list = str_to_int_func(list_1)
return sum(parse_list)
list_1 = [1, 2, 3, 4, 5]
print(get_total(str_to_int, list_1))

上面我們首先定義了一個函數str_to_int,目的是用於將字符類型的數字轉換成整型,然後定義一個求和函數,該函數接受一個字符串轉換成整型的函數參數以及一個待求和的參數列表。最後我們定義一個帶求和的列表,接著調用求和函數,但是我們仔細看一下,調用get_totoal函數的時候,我們傳遞了一個str_to_int對象,這個變量其實就是我們前面聲明的函數,它也可以和一般變量一樣作為參數傳遞給其它函數。當然這個例子沒什麼實際用處,實際也不會這麼寫,這裡只是為了讓大家明白,在python中,記住只是在python中,在其他語言不一定,函數也是一個對象,也是可以作為參數進行傳遞的。

知道了函數也是一個對象,可作為參數傳遞後,我們學習一下匿名函數。

lambda函數

匿名函數意思就是沒有名字的函數,作為初學者可能會很奇怪,沒有名字的函數?那怎麼調用這個函數,不是沒有名字麼?接下來會為你解答。匿名函數由於沒有名字,因此也不適用於涉及一大段的代碼塊,所以它又有另外一個說法,叫做一句話函數,就是說一條語句就可以寫完的函數。

匿名函數的一般形式是:

lambda param1:expression

即lambda關鍵詞+變量名稱+冒號+表達式。表達式將會對參數進行運算並返回結果。

看個例子:

# 定義並調用一個匿名函數,該函數將對參數進行+1並將結果返回
result = (lambda x: x + 1)(5)
print(result)
# 當然匿名函數也可以傳遞多個參數
result = (lambda x, y: x + y)(5, 6)
print(result)
# 不止可以對數值變量進行計算,還可以對列表進行處理,下面的代碼意思相當於result = [1,2,3,4,5] * 2
result = (lambda x: x * 2)([1, 2, 3, 4, 5]) # 不要誤認為會將列表的每個數都進行計算,實際上它是一個整體傳進去的,即x=[1,2,3,4,5]
print(result)

通過上面的例子我們知道怎麼定義和調用匿名函數了,也應該明白,我們不應該讓匿名函數做過多的事情,如果需要做過多的事情就要定義成普通函數。匿名函數適合那種一句話就可以完成的函數,這類函數定義成普通函數會過於臃腫,而定義成匿名函數則恰到好處。

接著解釋一下匿名函數怎麼調用的,上面的匿名函數是直接用括號括起來然後調用的,這樣對於初學者來說不太好理解,我再這麼寫個例子就應該明白了:

# 定義並調用一個匿名函數,該函數將對參數進行+1並將結果返回
my_func = lambda x: x + 1
print(my_func(5))

這裡我們把匿名函數賦值給一個變量,然後通過這個變量來調用匿名函數。就和普通函數一樣,可以通過函數名稱調用函數並傳遞值。

匿名函數真正的威力是和其它幾個python的高階函數結合使用,它們分別是map,reduce,filter,sorted。

map函數

map函數一般形式是:

map(func,seq)

其中func是一個函數變量,可以是普通函數也可以是匿名函數,seq是可迭代對象。關於什麼是可迭代對象本章節不會講,以後會有專門的章節講,現在我們可以把可迭代對象當成list,dict這些複合類型就行。

map的實際使用:

# map調用普通函數
def str_to_int(str_obj):
return int(str_obj)
result = map(str_to_int, ["1", "2", "3"])
print(list(result))
# map調用匿名函數
result = map(lambda x: int(x), ["1", "2", "3"])
print(list(result))
# 可以傳遞多個參數
result = map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6])
print(list(result))

輸出結果:

[1, 2, 3]
[1, 2, 3]
[5, 7, 9]

要注意的是,map函數會將參數的每一項都拿出來傳入給函數對象,而不是將參數作為一個整體傳入。並且map返回的是一個惰性的迭代對象,所以如果我們要拿返回結果,應該用list計算一下。

另外,傳遞多個參數和一個參數的計算方式是不同的,為了方便理解,請看下圖:

一個參數時,計算方式是這樣的:

"

沒有學不會的python


函數式編程

到現在為止,我們的沒有學不會python系列文章已經講了很多知識點了,如果是第一次刷到這篇文章的朋友可以去我主頁看一下以前寫的文章。前面講了很多知識點,每個知識點都輔以代碼作為理解和練手,這些例子都是用面向過程思想編寫的,面向過程的本質就是將一個個複雜問題拆解成簡單問題,意思就是將一個以實現某目的的程序劃分成一個個函數的意思,這就是面向過程的編程思想。

而函數式編程,雖然也是面向過程的一種編程思想,但它又跟一般的面向過程寫法有些不一樣,簡單說就是它更抽象更簡潔,而帶來的副作用就是,代碼比較難懂,執行效率也相對低一點。因此面向對象編程思想可分為兩種,一種是函數式編程另外一種是命令式編程,它們的區別是:

函數式編程關心數據的映射,命令式編程關心解決問題的步驟。翻譯成人話就是,函數式編程只負責處理數據的加工運算,不管代碼邏輯結構,是一種更加抽象的方法。命令式編程就關注於代碼邏輯結構,有時為了使代碼結構更合理更易懂,我們不介意用非常臃腫的寫法去完成一個運算目的。

python作為一門高級語言,自然也支持函數式編程,因為在python中一切皆是對象。可能有些朋友不知道對象是什麼意思,前面講過的那些變量就是對象,對象就是一個個在內存中擁有地址的變量。而函數,也是一種變量,在python中,由於函數也可以作為變量進行傳遞,所以python也支持函數式編程。

函數也是一個對象

要怎麼理解函數也是一個對象呢,最好的辦法就是通過代碼認識一下。

def str_to_int(str_list):
"""
將字符類型的數字轉換成整型
:param str_list:
:return:
"""
result = []
for item in str_list:
result.append(int(item))
return result
def get_total(str_to_int_func, list_1):
"""
對list_1求和
:param str_to_int:
:param list_1:
:return:
"""
parse_list = str_to_int_func(list_1)
return sum(parse_list)
list_1 = [1, 2, 3, 4, 5]
print(get_total(str_to_int, list_1))

上面我們首先定義了一個函數str_to_int,目的是用於將字符類型的數字轉換成整型,然後定義一個求和函數,該函數接受一個字符串轉換成整型的函數參數以及一個待求和的參數列表。最後我們定義一個帶求和的列表,接著調用求和函數,但是我們仔細看一下,調用get_totoal函數的時候,我們傳遞了一個str_to_int對象,這個變量其實就是我們前面聲明的函數,它也可以和一般變量一樣作為參數傳遞給其它函數。當然這個例子沒什麼實際用處,實際也不會這麼寫,這裡只是為了讓大家明白,在python中,記住只是在python中,在其他語言不一定,函數也是一個對象,也是可以作為參數進行傳遞的。

知道了函數也是一個對象,可作為參數傳遞後,我們學習一下匿名函數。

lambda函數

匿名函數意思就是沒有名字的函數,作為初學者可能會很奇怪,沒有名字的函數?那怎麼調用這個函數,不是沒有名字麼?接下來會為你解答。匿名函數由於沒有名字,因此也不適用於涉及一大段的代碼塊,所以它又有另外一個說法,叫做一句話函數,就是說一條語句就可以寫完的函數。

匿名函數的一般形式是:

lambda param1:expression

即lambda關鍵詞+變量名稱+冒號+表達式。表達式將會對參數進行運算並返回結果。

看個例子:

# 定義並調用一個匿名函數,該函數將對參數進行+1並將結果返回
result = (lambda x: x + 1)(5)
print(result)
# 當然匿名函數也可以傳遞多個參數
result = (lambda x, y: x + y)(5, 6)
print(result)
# 不止可以對數值變量進行計算,還可以對列表進行處理,下面的代碼意思相當於result = [1,2,3,4,5] * 2
result = (lambda x: x * 2)([1, 2, 3, 4, 5]) # 不要誤認為會將列表的每個數都進行計算,實際上它是一個整體傳進去的,即x=[1,2,3,4,5]
print(result)

通過上面的例子我們知道怎麼定義和調用匿名函數了,也應該明白,我們不應該讓匿名函數做過多的事情,如果需要做過多的事情就要定義成普通函數。匿名函數適合那種一句話就可以完成的函數,這類函數定義成普通函數會過於臃腫,而定義成匿名函數則恰到好處。

接著解釋一下匿名函數怎麼調用的,上面的匿名函數是直接用括號括起來然後調用的,這樣對於初學者來說不太好理解,我再這麼寫個例子就應該明白了:

# 定義並調用一個匿名函數,該函數將對參數進行+1並將結果返回
my_func = lambda x: x + 1
print(my_func(5))

這裡我們把匿名函數賦值給一個變量,然後通過這個變量來調用匿名函數。就和普通函數一樣,可以通過函數名稱調用函數並傳遞值。

匿名函數真正的威力是和其它幾個python的高階函數結合使用,它們分別是map,reduce,filter,sorted。

map函數

map函數一般形式是:

map(func,seq)

其中func是一個函數變量,可以是普通函數也可以是匿名函數,seq是可迭代對象。關於什麼是可迭代對象本章節不會講,以後會有專門的章節講,現在我們可以把可迭代對象當成list,dict這些複合類型就行。

map的實際使用:

# map調用普通函數
def str_to_int(str_obj):
return int(str_obj)
result = map(str_to_int, ["1", "2", "3"])
print(list(result))
# map調用匿名函數
result = map(lambda x: int(x), ["1", "2", "3"])
print(list(result))
# 可以傳遞多個參數
result = map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6])
print(list(result))

輸出結果:

[1, 2, 3]
[1, 2, 3]
[5, 7, 9]

要注意的是,map函數會將參數的每一項都拿出來傳入給函數對象,而不是將參數作為一個整體傳入。並且map返回的是一個惰性的迭代對象,所以如果我們要拿返回結果,應該用list計算一下。

另外,傳遞多個參數和一個參數的計算方式是不同的,為了方便理解,請看下圖:

一個參數時,計算方式是這樣的:

沒有學不會的python--函數式編程以及高階函數

即將參數的每一項循環計算輸出。

兩個參數時,計算方式是這樣的:

"

沒有學不會的python


函數式編程

到現在為止,我們的沒有學不會python系列文章已經講了很多知識點了,如果是第一次刷到這篇文章的朋友可以去我主頁看一下以前寫的文章。前面講了很多知識點,每個知識點都輔以代碼作為理解和練手,這些例子都是用面向過程思想編寫的,面向過程的本質就是將一個個複雜問題拆解成簡單問題,意思就是將一個以實現某目的的程序劃分成一個個函數的意思,這就是面向過程的編程思想。

而函數式編程,雖然也是面向過程的一種編程思想,但它又跟一般的面向過程寫法有些不一樣,簡單說就是它更抽象更簡潔,而帶來的副作用就是,代碼比較難懂,執行效率也相對低一點。因此面向對象編程思想可分為兩種,一種是函數式編程另外一種是命令式編程,它們的區別是:

函數式編程關心數據的映射,命令式編程關心解決問題的步驟。翻譯成人話就是,函數式編程只負責處理數據的加工運算,不管代碼邏輯結構,是一種更加抽象的方法。命令式編程就關注於代碼邏輯結構,有時為了使代碼結構更合理更易懂,我們不介意用非常臃腫的寫法去完成一個運算目的。

python作為一門高級語言,自然也支持函數式編程,因為在python中一切皆是對象。可能有些朋友不知道對象是什麼意思,前面講過的那些變量就是對象,對象就是一個個在內存中擁有地址的變量。而函數,也是一種變量,在python中,由於函數也可以作為變量進行傳遞,所以python也支持函數式編程。

函數也是一個對象

要怎麼理解函數也是一個對象呢,最好的辦法就是通過代碼認識一下。

def str_to_int(str_list):
"""
將字符類型的數字轉換成整型
:param str_list:
:return:
"""
result = []
for item in str_list:
result.append(int(item))
return result
def get_total(str_to_int_func, list_1):
"""
對list_1求和
:param str_to_int:
:param list_1:
:return:
"""
parse_list = str_to_int_func(list_1)
return sum(parse_list)
list_1 = [1, 2, 3, 4, 5]
print(get_total(str_to_int, list_1))

上面我們首先定義了一個函數str_to_int,目的是用於將字符類型的數字轉換成整型,然後定義一個求和函數,該函數接受一個字符串轉換成整型的函數參數以及一個待求和的參數列表。最後我們定義一個帶求和的列表,接著調用求和函數,但是我們仔細看一下,調用get_totoal函數的時候,我們傳遞了一個str_to_int對象,這個變量其實就是我們前面聲明的函數,它也可以和一般變量一樣作為參數傳遞給其它函數。當然這個例子沒什麼實際用處,實際也不會這麼寫,這裡只是為了讓大家明白,在python中,記住只是在python中,在其他語言不一定,函數也是一個對象,也是可以作為參數進行傳遞的。

知道了函數也是一個對象,可作為參數傳遞後,我們學習一下匿名函數。

lambda函數

匿名函數意思就是沒有名字的函數,作為初學者可能會很奇怪,沒有名字的函數?那怎麼調用這個函數,不是沒有名字麼?接下來會為你解答。匿名函數由於沒有名字,因此也不適用於涉及一大段的代碼塊,所以它又有另外一個說法,叫做一句話函數,就是說一條語句就可以寫完的函數。

匿名函數的一般形式是:

lambda param1:expression

即lambda關鍵詞+變量名稱+冒號+表達式。表達式將會對參數進行運算並返回結果。

看個例子:

# 定義並調用一個匿名函數,該函數將對參數進行+1並將結果返回
result = (lambda x: x + 1)(5)
print(result)
# 當然匿名函數也可以傳遞多個參數
result = (lambda x, y: x + y)(5, 6)
print(result)
# 不止可以對數值變量進行計算,還可以對列表進行處理,下面的代碼意思相當於result = [1,2,3,4,5] * 2
result = (lambda x: x * 2)([1, 2, 3, 4, 5]) # 不要誤認為會將列表的每個數都進行計算,實際上它是一個整體傳進去的,即x=[1,2,3,4,5]
print(result)

通過上面的例子我們知道怎麼定義和調用匿名函數了,也應該明白,我們不應該讓匿名函數做過多的事情,如果需要做過多的事情就要定義成普通函數。匿名函數適合那種一句話就可以完成的函數,這類函數定義成普通函數會過於臃腫,而定義成匿名函數則恰到好處。

接著解釋一下匿名函數怎麼調用的,上面的匿名函數是直接用括號括起來然後調用的,這樣對於初學者來說不太好理解,我再這麼寫個例子就應該明白了:

# 定義並調用一個匿名函數,該函數將對參數進行+1並將結果返回
my_func = lambda x: x + 1
print(my_func(5))

這裡我們把匿名函數賦值給一個變量,然後通過這個變量來調用匿名函數。就和普通函數一樣,可以通過函數名稱調用函數並傳遞值。

匿名函數真正的威力是和其它幾個python的高階函數結合使用,它們分別是map,reduce,filter,sorted。

map函數

map函數一般形式是:

map(func,seq)

其中func是一個函數變量,可以是普通函數也可以是匿名函數,seq是可迭代對象。關於什麼是可迭代對象本章節不會講,以後會有專門的章節講,現在我們可以把可迭代對象當成list,dict這些複合類型就行。

map的實際使用:

# map調用普通函數
def str_to_int(str_obj):
return int(str_obj)
result = map(str_to_int, ["1", "2", "3"])
print(list(result))
# map調用匿名函數
result = map(lambda x: int(x), ["1", "2", "3"])
print(list(result))
# 可以傳遞多個參數
result = map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6])
print(list(result))

輸出結果:

[1, 2, 3]
[1, 2, 3]
[5, 7, 9]

要注意的是,map函數會將參數的每一項都拿出來傳入給函數對象,而不是將參數作為一個整體傳入。並且map返回的是一個惰性的迭代對象,所以如果我們要拿返回結果,應該用list計算一下。

另外,傳遞多個參數和一個參數的計算方式是不同的,為了方便理解,請看下圖:

一個參數時,計算方式是這樣的:

沒有學不會的python--函數式編程以及高階函數

即將參數的每一項循環計算輸出。

兩個參數時,計算方式是這樣的:

沒有學不會的python--函數式編程以及高階函數

即將對應參數的對應項循環傳遞進行計算,比如上圖的就是x=[1,2,3]、y=[4,5,6],接著循環對應項進行計算,先取第一項就是x[0]+y[0]就是1+4,如此循環。

reduce函數

reduce函數的一般形式和map一樣也是:

reduce(func,seq)

不過值得注意的是,reduce在python3中被移植到了functools模塊中,所以我們要先引入才能使用。reduce的計算思想比較難以用語言描述,不過reduce翻譯成中文的意思就是合併。我們可以簡單的理解為合併運算。下面通過代碼來理解一下:

from functools import reduce
# 相當於求和
result = reduce(lambda x, y: x + y, [1, 2, 3])
print(result)
# 相當於連接字符串
result = reduce(lambda x, y: x + y, ["I", " Love", " you"])
print(result)

輸出結果:

6
I Love you

上述代碼實現了兩個功能,分別是求和和鏈接字符串。求和的計算過程翻譯成圖就是:

"

沒有學不會的python


函數式編程

到現在為止,我們的沒有學不會python系列文章已經講了很多知識點了,如果是第一次刷到這篇文章的朋友可以去我主頁看一下以前寫的文章。前面講了很多知識點,每個知識點都輔以代碼作為理解和練手,這些例子都是用面向過程思想編寫的,面向過程的本質就是將一個個複雜問題拆解成簡單問題,意思就是將一個以實現某目的的程序劃分成一個個函數的意思,這就是面向過程的編程思想。

而函數式編程,雖然也是面向過程的一種編程思想,但它又跟一般的面向過程寫法有些不一樣,簡單說就是它更抽象更簡潔,而帶來的副作用就是,代碼比較難懂,執行效率也相對低一點。因此面向對象編程思想可分為兩種,一種是函數式編程另外一種是命令式編程,它們的區別是:

函數式編程關心數據的映射,命令式編程關心解決問題的步驟。翻譯成人話就是,函數式編程只負責處理數據的加工運算,不管代碼邏輯結構,是一種更加抽象的方法。命令式編程就關注於代碼邏輯結構,有時為了使代碼結構更合理更易懂,我們不介意用非常臃腫的寫法去完成一個運算目的。

python作為一門高級語言,自然也支持函數式編程,因為在python中一切皆是對象。可能有些朋友不知道對象是什麼意思,前面講過的那些變量就是對象,對象就是一個個在內存中擁有地址的變量。而函數,也是一種變量,在python中,由於函數也可以作為變量進行傳遞,所以python也支持函數式編程。

函數也是一個對象

要怎麼理解函數也是一個對象呢,最好的辦法就是通過代碼認識一下。

def str_to_int(str_list):
"""
將字符類型的數字轉換成整型
:param str_list:
:return:
"""
result = []
for item in str_list:
result.append(int(item))
return result
def get_total(str_to_int_func, list_1):
"""
對list_1求和
:param str_to_int:
:param list_1:
:return:
"""
parse_list = str_to_int_func(list_1)
return sum(parse_list)
list_1 = [1, 2, 3, 4, 5]
print(get_total(str_to_int, list_1))

上面我們首先定義了一個函數str_to_int,目的是用於將字符類型的數字轉換成整型,然後定義一個求和函數,該函數接受一個字符串轉換成整型的函數參數以及一個待求和的參數列表。最後我們定義一個帶求和的列表,接著調用求和函數,但是我們仔細看一下,調用get_totoal函數的時候,我們傳遞了一個str_to_int對象,這個變量其實就是我們前面聲明的函數,它也可以和一般變量一樣作為參數傳遞給其它函數。當然這個例子沒什麼實際用處,實際也不會這麼寫,這裡只是為了讓大家明白,在python中,記住只是在python中,在其他語言不一定,函數也是一個對象,也是可以作為參數進行傳遞的。

知道了函數也是一個對象,可作為參數傳遞後,我們學習一下匿名函數。

lambda函數

匿名函數意思就是沒有名字的函數,作為初學者可能會很奇怪,沒有名字的函數?那怎麼調用這個函數,不是沒有名字麼?接下來會為你解答。匿名函數由於沒有名字,因此也不適用於涉及一大段的代碼塊,所以它又有另外一個說法,叫做一句話函數,就是說一條語句就可以寫完的函數。

匿名函數的一般形式是:

lambda param1:expression

即lambda關鍵詞+變量名稱+冒號+表達式。表達式將會對參數進行運算並返回結果。

看個例子:

# 定義並調用一個匿名函數,該函數將對參數進行+1並將結果返回
result = (lambda x: x + 1)(5)
print(result)
# 當然匿名函數也可以傳遞多個參數
result = (lambda x, y: x + y)(5, 6)
print(result)
# 不止可以對數值變量進行計算,還可以對列表進行處理,下面的代碼意思相當於result = [1,2,3,4,5] * 2
result = (lambda x: x * 2)([1, 2, 3, 4, 5]) # 不要誤認為會將列表的每個數都進行計算,實際上它是一個整體傳進去的,即x=[1,2,3,4,5]
print(result)

通過上面的例子我們知道怎麼定義和調用匿名函數了,也應該明白,我們不應該讓匿名函數做過多的事情,如果需要做過多的事情就要定義成普通函數。匿名函數適合那種一句話就可以完成的函數,這類函數定義成普通函數會過於臃腫,而定義成匿名函數則恰到好處。

接著解釋一下匿名函數怎麼調用的,上面的匿名函數是直接用括號括起來然後調用的,這樣對於初學者來說不太好理解,我再這麼寫個例子就應該明白了:

# 定義並調用一個匿名函數,該函數將對參數進行+1並將結果返回
my_func = lambda x: x + 1
print(my_func(5))

這裡我們把匿名函數賦值給一個變量,然後通過這個變量來調用匿名函數。就和普通函數一樣,可以通過函數名稱調用函數並傳遞值。

匿名函數真正的威力是和其它幾個python的高階函數結合使用,它們分別是map,reduce,filter,sorted。

map函數

map函數一般形式是:

map(func,seq)

其中func是一個函數變量,可以是普通函數也可以是匿名函數,seq是可迭代對象。關於什麼是可迭代對象本章節不會講,以後會有專門的章節講,現在我們可以把可迭代對象當成list,dict這些複合類型就行。

map的實際使用:

# map調用普通函數
def str_to_int(str_obj):
return int(str_obj)
result = map(str_to_int, ["1", "2", "3"])
print(list(result))
# map調用匿名函數
result = map(lambda x: int(x), ["1", "2", "3"])
print(list(result))
# 可以傳遞多個參數
result = map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6])
print(list(result))

輸出結果:

[1, 2, 3]
[1, 2, 3]
[5, 7, 9]

要注意的是,map函數會將參數的每一項都拿出來傳入給函數對象,而不是將參數作為一個整體傳入。並且map返回的是一個惰性的迭代對象,所以如果我們要拿返回結果,應該用list計算一下。

另外,傳遞多個參數和一個參數的計算方式是不同的,為了方便理解,請看下圖:

一個參數時,計算方式是這樣的:

沒有學不會的python--函數式編程以及高階函數

即將參數的每一項循環計算輸出。

兩個參數時,計算方式是這樣的:

沒有學不會的python--函數式編程以及高階函數

即將對應參數的對應項循環傳遞進行計算,比如上圖的就是x=[1,2,3]、y=[4,5,6],接著循環對應項進行計算,先取第一項就是x[0]+y[0]就是1+4,如此循環。

reduce函數

reduce函數的一般形式和map一樣也是:

reduce(func,seq)

不過值得注意的是,reduce在python3中被移植到了functools模塊中,所以我們要先引入才能使用。reduce的計算思想比較難以用語言描述,不過reduce翻譯成中文的意思就是合併。我們可以簡單的理解為合併運算。下面通過代碼來理解一下:

from functools import reduce
# 相當於求和
result = reduce(lambda x, y: x + y, [1, 2, 3])
print(result)
# 相當於連接字符串
result = reduce(lambda x, y: x + y, ["I", " Love", " you"])
print(result)

輸出結果:

6
I Love you

上述代碼實現了兩個功能,分別是求和和鏈接字符串。求和的計算過程翻譯成圖就是:

沒有學不會的python--函數式編程以及高階函數

第一次先將列表的前兩項傳入給x,y,然後計算和返回,再接著取列表的下一項跟返回的和繼續傳入給x,y接著求和,如此循環。

filter函數

filter函數的形式跟map也是一樣的,這裡不再重複。這個函數比較好理解,它就是把符合條件的值都過濾出來並返回。

比如下面的代碼就是將大於5的值都過濾出來返回:

result = filter(lambda x: x > 5, [2, 3, 5, 7, 8, 9])
print(list(result))

輸出結果:

[7, 8, 9]

我們可以用這個函數來做一些簡單的過濾操作。

sorted函數

sorted是python內置的一個排序函數,使用它,就不需要我們去寫排序算法了,而且它的使用非常靈活。廢話不多說,直接看例子:

# 簡單的對列表進行數字大小比較並升序輸出
result = sorted([23, 1, 34, 10])
print(result)
# 簡單的對列表進行數字大小比較並倒序輸出
result = sorted([23, 1, 34, 10], reverse=True)
print(result)
# 不僅列表,我們也可以操作字典
dict_1 = {"two": 2, "four": 4, "one": 1}
# 按值排序
result = sorted(dict_1.items(), key=lambda item: item[1])
print(result)
# 按鍵排序
result = sorted(dict_1.items(), key=lambda item: item[0])
print(result)

輸出結果:

[1, 10, 23, 34]
[34, 23, 10, 1]
[('one', 1), ('two', 2), ('four', 4)]
[('four', 4), ('one', 1), ('two', 2)]

sorted函數的更多用法就需要你們自己取摸索,對於初學者來說,這些就夠了。

函數式編程的利與弊

函數式編程有好的一面就有壞的一面,不是什麼情況都適合用函數式編程的,況且python並不完全支持函數式編程的所有特性。關於函數式編程的利與弊,我結合前面的例子做一個綜合的說明。假如我們要實現一個功能,需要先對數字字符進行轉換為整型然後再求和,求和之後,如果結果比10大就返回,比10小就丟棄。這麼一個功能如果用函數式來寫的話就是:

from functools import reduce
result = filter(lambda x: x > 10, [reduce(lambda x, y: x + y, list(map(lambda x: int(x), ['4', '5', '6']))),
reduce(lambda x, y: x + y, list(map(lambda x: int(x), ['1', '2', '3'])))])
print(list(result))

這個函數給你第一眼感覺是什麼?暈是吧。別說初學者,就是有經驗的人,看到這樣的寫法都頭疼,雖然很簡短的代碼就實現了這麼多功能,但是代碼閱讀性太差了,即使是本人,過段時間回過頭來,也未必知道自己寫的是什麼玩意。

如果我把它這樣寫呢:

def str_to_int(str_obj):
return int(str_obj)
def get_total(list_1):
total = 0
for item in list_1:
total += str_to_int(item)
return total
result_1 = get_total(['1', '2', '3'])
result_2 = get_total(['4', '5', '6'])
result = [result_1, result_2]
print(list(filter(lambda x: x > 10, result)))

這樣代碼是不是好很多,雖然代碼量多了,但是可閱讀性高了,你好我好大家好。

我們在選擇函數式編程的時候,切記不要混合使用,要易易懂為主,炫酷為次。python的函數式編程本質上是為了簡短的普通函數服務的,並不適合功能複雜的函數。而且有些公司明確規定不然程序員寫函數式編程,怕的就是以後你的代碼沒人看懂,不知道怎麼修改。

好了,今天就到這裡。

"

沒有學不會的python


函數式編程

到現在為止,我們的沒有學不會python系列文章已經講了很多知識點了,如果是第一次刷到這篇文章的朋友可以去我主頁看一下以前寫的文章。前面講了很多知識點,每個知識點都輔以代碼作為理解和練手,這些例子都是用面向過程思想編寫的,面向過程的本質就是將一個個複雜問題拆解成簡單問題,意思就是將一個以實現某目的的程序劃分成一個個函數的意思,這就是面向過程的編程思想。

而函數式編程,雖然也是面向過程的一種編程思想,但它又跟一般的面向過程寫法有些不一樣,簡單說就是它更抽象更簡潔,而帶來的副作用就是,代碼比較難懂,執行效率也相對低一點。因此面向對象編程思想可分為兩種,一種是函數式編程另外一種是命令式編程,它們的區別是:

函數式編程關心數據的映射,命令式編程關心解決問題的步驟。翻譯成人話就是,函數式編程只負責處理數據的加工運算,不管代碼邏輯結構,是一種更加抽象的方法。命令式編程就關注於代碼邏輯結構,有時為了使代碼結構更合理更易懂,我們不介意用非常臃腫的寫法去完成一個運算目的。

python作為一門高級語言,自然也支持函數式編程,因為在python中一切皆是對象。可能有些朋友不知道對象是什麼意思,前面講過的那些變量就是對象,對象就是一個個在內存中擁有地址的變量。而函數,也是一種變量,在python中,由於函數也可以作為變量進行傳遞,所以python也支持函數式編程。

函數也是一個對象

要怎麼理解函數也是一個對象呢,最好的辦法就是通過代碼認識一下。

def str_to_int(str_list):
"""
將字符類型的數字轉換成整型
:param str_list:
:return:
"""
result = []
for item in str_list:
result.append(int(item))
return result
def get_total(str_to_int_func, list_1):
"""
對list_1求和
:param str_to_int:
:param list_1:
:return:
"""
parse_list = str_to_int_func(list_1)
return sum(parse_list)
list_1 = [1, 2, 3, 4, 5]
print(get_total(str_to_int, list_1))

上面我們首先定義了一個函數str_to_int,目的是用於將字符類型的數字轉換成整型,然後定義一個求和函數,該函數接受一個字符串轉換成整型的函數參數以及一個待求和的參數列表。最後我們定義一個帶求和的列表,接著調用求和函數,但是我們仔細看一下,調用get_totoal函數的時候,我們傳遞了一個str_to_int對象,這個變量其實就是我們前面聲明的函數,它也可以和一般變量一樣作為參數傳遞給其它函數。當然這個例子沒什麼實際用處,實際也不會這麼寫,這裡只是為了讓大家明白,在python中,記住只是在python中,在其他語言不一定,函數也是一個對象,也是可以作為參數進行傳遞的。

知道了函數也是一個對象,可作為參數傳遞後,我們學習一下匿名函數。

lambda函數

匿名函數意思就是沒有名字的函數,作為初學者可能會很奇怪,沒有名字的函數?那怎麼調用這個函數,不是沒有名字麼?接下來會為你解答。匿名函數由於沒有名字,因此也不適用於涉及一大段的代碼塊,所以它又有另外一個說法,叫做一句話函數,就是說一條語句就可以寫完的函數。

匿名函數的一般形式是:

lambda param1:expression

即lambda關鍵詞+變量名稱+冒號+表達式。表達式將會對參數進行運算並返回結果。

看個例子:

# 定義並調用一個匿名函數,該函數將對參數進行+1並將結果返回
result = (lambda x: x + 1)(5)
print(result)
# 當然匿名函數也可以傳遞多個參數
result = (lambda x, y: x + y)(5, 6)
print(result)
# 不止可以對數值變量進行計算,還可以對列表進行處理,下面的代碼意思相當於result = [1,2,3,4,5] * 2
result = (lambda x: x * 2)([1, 2, 3, 4, 5]) # 不要誤認為會將列表的每個數都進行計算,實際上它是一個整體傳進去的,即x=[1,2,3,4,5]
print(result)

通過上面的例子我們知道怎麼定義和調用匿名函數了,也應該明白,我們不應該讓匿名函數做過多的事情,如果需要做過多的事情就要定義成普通函數。匿名函數適合那種一句話就可以完成的函數,這類函數定義成普通函數會過於臃腫,而定義成匿名函數則恰到好處。

接著解釋一下匿名函數怎麼調用的,上面的匿名函數是直接用括號括起來然後調用的,這樣對於初學者來說不太好理解,我再這麼寫個例子就應該明白了:

# 定義並調用一個匿名函數,該函數將對參數進行+1並將結果返回
my_func = lambda x: x + 1
print(my_func(5))

這裡我們把匿名函數賦值給一個變量,然後通過這個變量來調用匿名函數。就和普通函數一樣,可以通過函數名稱調用函數並傳遞值。

匿名函數真正的威力是和其它幾個python的高階函數結合使用,它們分別是map,reduce,filter,sorted。

map函數

map函數一般形式是:

map(func,seq)

其中func是一個函數變量,可以是普通函數也可以是匿名函數,seq是可迭代對象。關於什麼是可迭代對象本章節不會講,以後會有專門的章節講,現在我們可以把可迭代對象當成list,dict這些複合類型就行。

map的實際使用:

# map調用普通函數
def str_to_int(str_obj):
return int(str_obj)
result = map(str_to_int, ["1", "2", "3"])
print(list(result))
# map調用匿名函數
result = map(lambda x: int(x), ["1", "2", "3"])
print(list(result))
# 可以傳遞多個參數
result = map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6])
print(list(result))

輸出結果:

[1, 2, 3]
[1, 2, 3]
[5, 7, 9]

要注意的是,map函數會將參數的每一項都拿出來傳入給函數對象,而不是將參數作為一個整體傳入。並且map返回的是一個惰性的迭代對象,所以如果我們要拿返回結果,應該用list計算一下。

另外,傳遞多個參數和一個參數的計算方式是不同的,為了方便理解,請看下圖:

一個參數時,計算方式是這樣的:

沒有學不會的python--函數式編程以及高階函數

即將參數的每一項循環計算輸出。

兩個參數時,計算方式是這樣的:

沒有學不會的python--函數式編程以及高階函數

即將對應參數的對應項循環傳遞進行計算,比如上圖的就是x=[1,2,3]、y=[4,5,6],接著循環對應項進行計算,先取第一項就是x[0]+y[0]就是1+4,如此循環。

reduce函數

reduce函數的一般形式和map一樣也是:

reduce(func,seq)

不過值得注意的是,reduce在python3中被移植到了functools模塊中,所以我們要先引入才能使用。reduce的計算思想比較難以用語言描述,不過reduce翻譯成中文的意思就是合併。我們可以簡單的理解為合併運算。下面通過代碼來理解一下:

from functools import reduce
# 相當於求和
result = reduce(lambda x, y: x + y, [1, 2, 3])
print(result)
# 相當於連接字符串
result = reduce(lambda x, y: x + y, ["I", " Love", " you"])
print(result)

輸出結果:

6
I Love you

上述代碼實現了兩個功能,分別是求和和鏈接字符串。求和的計算過程翻譯成圖就是:

沒有學不會的python--函數式編程以及高階函數

第一次先將列表的前兩項傳入給x,y,然後計算和返回,再接著取列表的下一項跟返回的和繼續傳入給x,y接著求和,如此循環。

filter函數

filter函數的形式跟map也是一樣的,這裡不再重複。這個函數比較好理解,它就是把符合條件的值都過濾出來並返回。

比如下面的代碼就是將大於5的值都過濾出來返回:

result = filter(lambda x: x > 5, [2, 3, 5, 7, 8, 9])
print(list(result))

輸出結果:

[7, 8, 9]

我們可以用這個函數來做一些簡單的過濾操作。

sorted函數

sorted是python內置的一個排序函數,使用它,就不需要我們去寫排序算法了,而且它的使用非常靈活。廢話不多說,直接看例子:

# 簡單的對列表進行數字大小比較並升序輸出
result = sorted([23, 1, 34, 10])
print(result)
# 簡單的對列表進行數字大小比較並倒序輸出
result = sorted([23, 1, 34, 10], reverse=True)
print(result)
# 不僅列表,我們也可以操作字典
dict_1 = {"two": 2, "four": 4, "one": 1}
# 按值排序
result = sorted(dict_1.items(), key=lambda item: item[1])
print(result)
# 按鍵排序
result = sorted(dict_1.items(), key=lambda item: item[0])
print(result)

輸出結果:

[1, 10, 23, 34]
[34, 23, 10, 1]
[('one', 1), ('two', 2), ('four', 4)]
[('four', 4), ('one', 1), ('two', 2)]

sorted函數的更多用法就需要你們自己取摸索,對於初學者來說,這些就夠了。

函數式編程的利與弊

函數式編程有好的一面就有壞的一面,不是什麼情況都適合用函數式編程的,況且python並不完全支持函數式編程的所有特性。關於函數式編程的利與弊,我結合前面的例子做一個綜合的說明。假如我們要實現一個功能,需要先對數字字符進行轉換為整型然後再求和,求和之後,如果結果比10大就返回,比10小就丟棄。這麼一個功能如果用函數式來寫的話就是:

from functools import reduce
result = filter(lambda x: x > 10, [reduce(lambda x, y: x + y, list(map(lambda x: int(x), ['4', '5', '6']))),
reduce(lambda x, y: x + y, list(map(lambda x: int(x), ['1', '2', '3'])))])
print(list(result))

這個函數給你第一眼感覺是什麼?暈是吧。別說初學者,就是有經驗的人,看到這樣的寫法都頭疼,雖然很簡短的代碼就實現了這麼多功能,但是代碼閱讀性太差了,即使是本人,過段時間回過頭來,也未必知道自己寫的是什麼玩意。

如果我把它這樣寫呢:

def str_to_int(str_obj):
return int(str_obj)
def get_total(list_1):
total = 0
for item in list_1:
total += str_to_int(item)
return total
result_1 = get_total(['1', '2', '3'])
result_2 = get_total(['4', '5', '6'])
result = [result_1, result_2]
print(list(filter(lambda x: x > 10, result)))

這樣代碼是不是好很多,雖然代碼量多了,但是可閱讀性高了,你好我好大家好。

我們在選擇函數式編程的時候,切記不要混合使用,要易易懂為主,炫酷為次。python的函數式編程本質上是為了簡短的普通函數服務的,並不適合功能複雜的函數。而且有些公司明確規定不然程序員寫函數式編程,怕的就是以後你的代碼沒人看懂,不知道怎麼修改。

好了,今天就到這裡。

沒有學不會的python--函數式編程以及高階函數

如果對我的文章感興趣,可以關注我的主頁也可以關注我的公眾號:

"

沒有學不會的python


函數式編程

到現在為止,我們的沒有學不會python系列文章已經講了很多知識點了,如果是第一次刷到這篇文章的朋友可以去我主頁看一下以前寫的文章。前面講了很多知識點,每個知識點都輔以代碼作為理解和練手,這些例子都是用面向過程思想編寫的,面向過程的本質就是將一個個複雜問題拆解成簡單問題,意思就是將一個以實現某目的的程序劃分成一個個函數的意思,這就是面向過程的編程思想。

而函數式編程,雖然也是面向過程的一種編程思想,但它又跟一般的面向過程寫法有些不一樣,簡單說就是它更抽象更簡潔,而帶來的副作用就是,代碼比較難懂,執行效率也相對低一點。因此面向對象編程思想可分為兩種,一種是函數式編程另外一種是命令式編程,它們的區別是:

函數式編程關心數據的映射,命令式編程關心解決問題的步驟。翻譯成人話就是,函數式編程只負責處理數據的加工運算,不管代碼邏輯結構,是一種更加抽象的方法。命令式編程就關注於代碼邏輯結構,有時為了使代碼結構更合理更易懂,我們不介意用非常臃腫的寫法去完成一個運算目的。

python作為一門高級語言,自然也支持函數式編程,因為在python中一切皆是對象。可能有些朋友不知道對象是什麼意思,前面講過的那些變量就是對象,對象就是一個個在內存中擁有地址的變量。而函數,也是一種變量,在python中,由於函數也可以作為變量進行傳遞,所以python也支持函數式編程。

函數也是一個對象

要怎麼理解函數也是一個對象呢,最好的辦法就是通過代碼認識一下。

def str_to_int(str_list):
"""
將字符類型的數字轉換成整型
:param str_list:
:return:
"""
result = []
for item in str_list:
result.append(int(item))
return result
def get_total(str_to_int_func, list_1):
"""
對list_1求和
:param str_to_int:
:param list_1:
:return:
"""
parse_list = str_to_int_func(list_1)
return sum(parse_list)
list_1 = [1, 2, 3, 4, 5]
print(get_total(str_to_int, list_1))

上面我們首先定義了一個函數str_to_int,目的是用於將字符類型的數字轉換成整型,然後定義一個求和函數,該函數接受一個字符串轉換成整型的函數參數以及一個待求和的參數列表。最後我們定義一個帶求和的列表,接著調用求和函數,但是我們仔細看一下,調用get_totoal函數的時候,我們傳遞了一個str_to_int對象,這個變量其實就是我們前面聲明的函數,它也可以和一般變量一樣作為參數傳遞給其它函數。當然這個例子沒什麼實際用處,實際也不會這麼寫,這裡只是為了讓大家明白,在python中,記住只是在python中,在其他語言不一定,函數也是一個對象,也是可以作為參數進行傳遞的。

知道了函數也是一個對象,可作為參數傳遞後,我們學習一下匿名函數。

lambda函數

匿名函數意思就是沒有名字的函數,作為初學者可能會很奇怪,沒有名字的函數?那怎麼調用這個函數,不是沒有名字麼?接下來會為你解答。匿名函數由於沒有名字,因此也不適用於涉及一大段的代碼塊,所以它又有另外一個說法,叫做一句話函數,就是說一條語句就可以寫完的函數。

匿名函數的一般形式是:

lambda param1:expression

即lambda關鍵詞+變量名稱+冒號+表達式。表達式將會對參數進行運算並返回結果。

看個例子:

# 定義並調用一個匿名函數,該函數將對參數進行+1並將結果返回
result = (lambda x: x + 1)(5)
print(result)
# 當然匿名函數也可以傳遞多個參數
result = (lambda x, y: x + y)(5, 6)
print(result)
# 不止可以對數值變量進行計算,還可以對列表進行處理,下面的代碼意思相當於result = [1,2,3,4,5] * 2
result = (lambda x: x * 2)([1, 2, 3, 4, 5]) # 不要誤認為會將列表的每個數都進行計算,實際上它是一個整體傳進去的,即x=[1,2,3,4,5]
print(result)

通過上面的例子我們知道怎麼定義和調用匿名函數了,也應該明白,我們不應該讓匿名函數做過多的事情,如果需要做過多的事情就要定義成普通函數。匿名函數適合那種一句話就可以完成的函數,這類函數定義成普通函數會過於臃腫,而定義成匿名函數則恰到好處。

接著解釋一下匿名函數怎麼調用的,上面的匿名函數是直接用括號括起來然後調用的,這樣對於初學者來說不太好理解,我再這麼寫個例子就應該明白了:

# 定義並調用一個匿名函數,該函數將對參數進行+1並將結果返回
my_func = lambda x: x + 1
print(my_func(5))

這裡我們把匿名函數賦值給一個變量,然後通過這個變量來調用匿名函數。就和普通函數一樣,可以通過函數名稱調用函數並傳遞值。

匿名函數真正的威力是和其它幾個python的高階函數結合使用,它們分別是map,reduce,filter,sorted。

map函數

map函數一般形式是:

map(func,seq)

其中func是一個函數變量,可以是普通函數也可以是匿名函數,seq是可迭代對象。關於什麼是可迭代對象本章節不會講,以後會有專門的章節講,現在我們可以把可迭代對象當成list,dict這些複合類型就行。

map的實際使用:

# map調用普通函數
def str_to_int(str_obj):
return int(str_obj)
result = map(str_to_int, ["1", "2", "3"])
print(list(result))
# map調用匿名函數
result = map(lambda x: int(x), ["1", "2", "3"])
print(list(result))
# 可以傳遞多個參數
result = map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6])
print(list(result))

輸出結果:

[1, 2, 3]
[1, 2, 3]
[5, 7, 9]

要注意的是,map函數會將參數的每一項都拿出來傳入給函數對象,而不是將參數作為一個整體傳入。並且map返回的是一個惰性的迭代對象,所以如果我們要拿返回結果,應該用list計算一下。

另外,傳遞多個參數和一個參數的計算方式是不同的,為了方便理解,請看下圖:

一個參數時,計算方式是這樣的:

沒有學不會的python--函數式編程以及高階函數

即將參數的每一項循環計算輸出。

兩個參數時,計算方式是這樣的:

沒有學不會的python--函數式編程以及高階函數

即將對應參數的對應項循環傳遞進行計算,比如上圖的就是x=[1,2,3]、y=[4,5,6],接著循環對應項進行計算,先取第一項就是x[0]+y[0]就是1+4,如此循環。

reduce函數

reduce函數的一般形式和map一樣也是:

reduce(func,seq)

不過值得注意的是,reduce在python3中被移植到了functools模塊中,所以我們要先引入才能使用。reduce的計算思想比較難以用語言描述,不過reduce翻譯成中文的意思就是合併。我們可以簡單的理解為合併運算。下面通過代碼來理解一下:

from functools import reduce
# 相當於求和
result = reduce(lambda x, y: x + y, [1, 2, 3])
print(result)
# 相當於連接字符串
result = reduce(lambda x, y: x + y, ["I", " Love", " you"])
print(result)

輸出結果:

6
I Love you

上述代碼實現了兩個功能,分別是求和和鏈接字符串。求和的計算過程翻譯成圖就是:

沒有學不會的python--函數式編程以及高階函數

第一次先將列表的前兩項傳入給x,y,然後計算和返回,再接著取列表的下一項跟返回的和繼續傳入給x,y接著求和,如此循環。

filter函數

filter函數的形式跟map也是一樣的,這裡不再重複。這個函數比較好理解,它就是把符合條件的值都過濾出來並返回。

比如下面的代碼就是將大於5的值都過濾出來返回:

result = filter(lambda x: x > 5, [2, 3, 5, 7, 8, 9])
print(list(result))

輸出結果:

[7, 8, 9]

我們可以用這個函數來做一些簡單的過濾操作。

sorted函數

sorted是python內置的一個排序函數,使用它,就不需要我們去寫排序算法了,而且它的使用非常靈活。廢話不多說,直接看例子:

# 簡單的對列表進行數字大小比較並升序輸出
result = sorted([23, 1, 34, 10])
print(result)
# 簡單的對列表進行數字大小比較並倒序輸出
result = sorted([23, 1, 34, 10], reverse=True)
print(result)
# 不僅列表,我們也可以操作字典
dict_1 = {"two": 2, "four": 4, "one": 1}
# 按值排序
result = sorted(dict_1.items(), key=lambda item: item[1])
print(result)
# 按鍵排序
result = sorted(dict_1.items(), key=lambda item: item[0])
print(result)

輸出結果:

[1, 10, 23, 34]
[34, 23, 10, 1]
[('one', 1), ('two', 2), ('four', 4)]
[('four', 4), ('one', 1), ('two', 2)]

sorted函數的更多用法就需要你們自己取摸索,對於初學者來說,這些就夠了。

函數式編程的利與弊

函數式編程有好的一面就有壞的一面,不是什麼情況都適合用函數式編程的,況且python並不完全支持函數式編程的所有特性。關於函數式編程的利與弊,我結合前面的例子做一個綜合的說明。假如我們要實現一個功能,需要先對數字字符進行轉換為整型然後再求和,求和之後,如果結果比10大就返回,比10小就丟棄。這麼一個功能如果用函數式來寫的話就是:

from functools import reduce
result = filter(lambda x: x > 10, [reduce(lambda x, y: x + y, list(map(lambda x: int(x), ['4', '5', '6']))),
reduce(lambda x, y: x + y, list(map(lambda x: int(x), ['1', '2', '3'])))])
print(list(result))

這個函數給你第一眼感覺是什麼?暈是吧。別說初學者,就是有經驗的人,看到這樣的寫法都頭疼,雖然很簡短的代碼就實現了這麼多功能,但是代碼閱讀性太差了,即使是本人,過段時間回過頭來,也未必知道自己寫的是什麼玩意。

如果我把它這樣寫呢:

def str_to_int(str_obj):
return int(str_obj)
def get_total(list_1):
total = 0
for item in list_1:
total += str_to_int(item)
return total
result_1 = get_total(['1', '2', '3'])
result_2 = get_total(['4', '5', '6'])
result = [result_1, result_2]
print(list(filter(lambda x: x > 10, result)))

這樣代碼是不是好很多,雖然代碼量多了,但是可閱讀性高了,你好我好大家好。

我們在選擇函數式編程的時候,切記不要混合使用,要易易懂為主,炫酷為次。python的函數式編程本質上是為了簡短的普通函數服務的,並不適合功能複雜的函數。而且有些公司明確規定不然程序員寫函數式編程,怕的就是以後你的代碼沒人看懂,不知道怎麼修改。

好了,今天就到這裡。

沒有學不會的python--函數式編程以及高階函數

如果對我的文章感興趣,可以關注我的主頁也可以關注我的公眾號:

沒有學不會的python--函數式編程以及高階函數

"

相關推薦

推薦中...