日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

函数式编程filter、map、reduce

發布時間:2025/4/5 编程问答 12 豆豆
生活随笔 收集整理的這篇文章主要介紹了 函数式编程filter、map、reduce 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

函數式編程filter、map、reduce

(本文是一篇學習筆記和自己對filter、map、reduce的理解
參考:link.
作為一名半路出家的程序員,還記得第一門學習的編程語言是C,那種面向過程設計的語言風格很適合做事的流程和方式,很容易讓人上手。但是C 語言雖然簡單靈活,能夠讓程序員在高級語言特性之上輕松進行底層上的微觀控制,被譽為“高級語言中的匯編語言”,但其基于過程和底層的設計初衷又成了它的短板(例如內存的申請釋放完全由程序員控制,這就會帶來很多的意外驚喜)。
后面慢慢接受到了面向對象的程序設計,學習了C++,Java,Python等語言,逐漸感受到對象化對于編程的優勢,面向對象編程不夠友好地就是代碼閱讀體驗不佳,因為很多方法都封裝在了接口或者類里面,對其行為不仔細閱讀代碼有時不是很好把握,但或許這就是萬物皆對象的魅力所在吧。
最近接觸了一點點函數式編程。

什么是函數式編程?

學習過數學應該都知道函數,如:

f(x)=5x^2+4x+3 g(x)=2f(x)+5=10x^2+8x+11 h(x)=f(x)+g(x)=15x^2+12x+14

假設 f(x) 是一個函數,g(x) 是第二個函數,把 f(x) 這個函數套下來,并展開。然后還可以定義一個由兩個一元函數組合成的二元函數,還可以做遞歸,下面這個函數定義就是斐波那契數列。

f(x)=f(x-1)+f(x-2)

對于函數式編程來說,它只關心定義輸入數據和輸出數據相關的關系,數學表達式里面其實是在做一種映射(mapping),輸入的數據和輸出的數據關系是什么樣的,是用函數來定義的
函數式編程有以下特點。特征
stateless:函數不維護任何狀態。函數式編程的核心精神是 stateless,簡而言之就是它不能存在狀態,打個比方,你給我數據我處理完扔出來。里面的數據是不變的。
immutable:輸入數據是不能動的,動了輸入數據就有危險,所以要返回新的數據集。
優勢
沒有狀態就沒有傷害。
并行執行無傷害。
Copy-Paste 重構代碼無傷害。
函數的執行沒有順序上的問題。

函數式編程也很簡單容易,例如: // 非函數式,不是pure funciton,有狀態 int cnt; void increment(){cnt++; }// 函數式,pure function, 無狀態 int increment(int cnt){return cnt+1; }

為什么需要函數式編程?

編程語言是一種工具,編程語言的發展也是朝著越來越高效,方便的路徑發展。隨著各種語言的出現,程序員已經不再局限于各種語言,而是聚焦于業務,這就要求程序具有抽象的能力,能解決通用問題,這就是編程范式。
在程序世界中,編程工作更多的是解決業務上的問題,而不是計算機的問題,我們需要更為貼近業務、更為抽象的語言,如典型的面向對象語言 C++ 和 Java 等。
函數式編程的理念:
把函數當成變量來用,關注描述問題而不是怎么實現,這樣可以讓代碼更易讀。
因為函數返回里面的這個函數,所以函數關注的是表達式,關注的是描述這個問題,而不是怎么實現這個事情。

函數式編程關注的是:describe what to do, rather than how to do it
過程式編程范式叫做 Imperative Programming – 指令式編程,而把函數式編程范式叫做 Declarative Programming – 聲明式編程

函數式語言的三套件

函數式語言有三套件,Map、Reduce 和 Filter,在學習得時候理解不是很好,在此記錄幾個例子復習一下。

Map

map() 會根據提供的函數對指定序列做映射。

第一個參數 function 以參數序列中的每一個元素調用 function 函數,返回包含每次 function 函數返回值的新列表。

# 傳統的非函數式 upname =['HAO', 'CHEN', 'COOLSHELL'] lowname =[] for i in range(len(upname)):lowname.append( upname[i].lower() )# 函數式 def toUpper(item):return item.upper()upper_name = map(toUpper, ["hao", "chen", "coolshell"])print(upper_name) # 輸出 ['HAO', 'CHEN', 'COOLSHELL']map(lambda x: x ** 2, [1, 2, 3, 4, 5]) # 使用 lambda 匿名函數

reduce

reduce() 函數會對參數序列中元素進行累積。

函數將一個數據集合(鏈表,元組等)中的所有數據進行下列操作:用傳給 reduce 中的函數 function(有兩個參數)先對集合中的第 1、2 個元素進行操作,得到的結果再與第三個數據用 function 函數運算,最后得到一個結果。[reduce是減少的意思,每次頭用函數合并前兩個數據,知道集合中只有一個數據為止]

from functools import reducedef add(x, y) : # 兩數相加return x + y sum1 = reduce(add, [1,2,3,4,5]) # 計算列表和:1+2+3+4+5 sum2 = reduce(lambda x, y: x+y, [1,2,3,4,5]) # 使用 lambda 匿名函數

Filter

filter() 函數用于過濾序列,過濾掉不符合條件的元素,返回由符合條件元素組成的新列表。
該接收兩個參數,第一個為函數,第二個為序列,序列的每個元素作為參數傳遞給函數進行判斷,然后返回 True 或 False,最后將返回 True 的元素放到新列表中

import math def is_sqr(x):return math.sqrt(x) % 1 == 0newlist = filter(is_sqr, range(1, 101)) print(newlist)a = filter(lambda x: x % 2 == 0, range(10))

Map、Reduce 和 Filter是輪子,可以合起來造汽車:
計算數組中正數的平均值

# 計算數組中正數的平均值 num = [2, -5, 9, 7, -2, 5, 3, 1, 0, -3, 8] positive_num_cnt = 0 positive_num_sum = 0 for i in range(len(num)):if num[i] > 0:positive_num_cnt += 1positive_num_sum += num[i]if positive_num_cnt > 0:average = positive_num_sum / positive_num_cntprint(average)#計算數組中正數的平均值 positive_num = list(filter(lambda x: x>0, num)) #python2返回事list,python2返回時filter對象,需要轉換 average = reduce(lambda x,y: x+y, positive_num) / len( positive_num )

函數式編程的抽象:把業務抽象為一個個函數:
例如:把一個列表中偶數*3并轉為字符串輸出

def even_filter(nums):for num in nums:if num % 2 == 0:yield num def multiply_by_three(nums):for num in nums:yield num * 3 def convert_to_string(nums):for num in nums:yield 'The Number: %s' % numnums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 三個函數串起來 pipeline = convert_to_string(multiply_by_three(even_filter(nums)))

總結

以上是生活随笔為你收集整理的函数式编程filter、map、reduce的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。