久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    10分鐘學習函數式Python

     lllsztz 2019-12-28
    10分鐘學習函數式Python

    在這篇10分鐘的文章中,您將學習Python中的函數式范型。您還將學習列表推導式。

    目錄

    1. 函數式范式
    2. Python的map函數是如何運行的
    3. Python中的lambda表達式
    4. Python中的reduce函數
    5. filter函數
    6. Python中的高階函數
    7. 帶有函數的部分應用
    8. 函數編程不是Python化
    9. 列表推導式
    10. 任何可迭代對象的推導式
    11. 結論

    函數式范式

    在命令式編程范式中,我們通過給計算機一個任務序列來執行任務,然后計算機會執行這些任務。在執行它們時,計算機可以改變狀態。例如,我們設A = 5,然后改變A的值。因為我們的A是變量,所以它內部的值是變化的。

    在函數式編程范式中,我們不告訴計算機去做什么,而是告訴它是什么東西。一個數的最大公約數是什么,等等。

    變量不會變化。一旦我們設置了一個變量,它就會永遠保持這種狀態。因此,函數在函數式范型中沒有副作用。副作用就是函數改變了它外部的東西。讓我們來看一個例子:

    10分鐘學習函數式Python

    輸出是5。在函數式范型中,改變變量是一個很大的禁忌,而讓函數影響它們范圍之外的東西也是一個大大的禁忌。函數唯一能做的就是計算某些東西并返回它。

    現在您可能會想“沒有變量,就沒有副作用?為什么這很好?”問得好,讀這篇文章的古怪陌生人。

    如果一個函數使用相同的參數被調用兩次,那么它肯定會返回相同的結果。如果您學過數學函數,您就會喜歡這一點。我們稱之為函數的引用透明性。由于函數沒有副作用,如果我們構建一個計算程序,我們就可以加快該程序的速度。如果程序知道func(2)等于3,我們可以將其存儲在一個表中。這將防止程序在我們已經知道答案的情況下去運行相同的函數。

    通常,在函數式編程中,我們不使用循環,我們使用遞歸。遞歸是一個數學概念,它意味著“自食其力”。對于遞歸函數,該函數將自己作為一個子函數進行調用。下面是Python中遞歸函數的一個很好的例子:

    10分鐘學習函數式Python

    一些編程語言也很懶。這意味著他們直到最后一秒才開始計算或做任何事情。如果我們編寫一些代碼來執行2 + 2,一個函數式程序只會在我們需要使用結果時才會計算這個結果。我們很快就會探討Python中的惰性。

    Python的map函數是如何運行的

    為了理解映射,讓我們首先看看什么是可迭代對象。一個可迭代對象是我們可以迭代的任何東西。這些是列表或數組,但是Python有許多不同的可迭代對象。我們甚至可以通過實現魔術方法來創建我們自己的可迭代對象。一個魔術方法就像一個API,它可以幫助我們的對象變得更Python化。要使一個對象成為一個可迭代對象,我們需要實現2個魔術方法:

    10分鐘學習函數式Python

    第一個魔術方法是__iter__,或者叫特殊iter(雙下劃線)方法,它會返回迭代對象,我們通常在循環開始時使用它。特殊next方法,__next__,會返回下一個對象是什么。

    讓我們來看看這個:

    10分鐘學習函數式Python

    這將輸出:

    10分鐘學習函數式Python

    在Python中,迭代器是一個對象,它只有一個簡單的__iter__魔術方法。這意味著我們可以訪問該對象中的位置,但不能遍歷該對象。有些對象有魔術方法__next__,但沒有__iter__魔術方法,如sets(將在本文后面討論)。對于本文,我們將假設我們接觸的所有東西都是一個可迭代的對象。

    現在我們知道了什么是可迭代對象,讓我們回到map函數。

    map函數允許我們將一個函數應用到一個可迭代對象中的每個項。我們希望將一個函數應用到一個列表中的每個項,但是要知道這對大多數可迭代對象來說都是可行的。map的語法接受兩個輸入,即要應用的函數和可迭代的對象。

    10分鐘學習函數式Python

    假設我們有一個像這樣的數字列表:

    10分鐘學習函數式Python

    我們相對每個數字進行平方,我們可以像這樣寫代碼:

    10分鐘學習函數式Python

    函數式Python是惰性的。如果我們不包含list(),函數將存儲該可迭代對象的定義,而不是列表本身。我們需要告訴Python“把這個轉換成一個列表”,以便我們使用它。

    在Python中突然從非惰性求值變成惰性求值是很奇怪的。如果您更多地以函數式思維而不是命令式思維進行思考,您就會習慣它。

    現在寫一個像square(num)這樣的普通函數就很好了,但是它看起來不夠好。我們必須定義一個完整的函數才可以在一個映射中使用它嗎?好吧,我們可以使用lambda(匿名)函數在map中定義一個函數。

    Python中的lambda表達式

    Lambda函數是一個只有一行代碼的函數,適用于短期內使用。我們經常將它們隨同高階函數,如filter、map和reduce函數,一起使用。這個lambda表達式會對傳給它的數字進行平方:

    10分鐘學習函數式Python

    現在我們來運行這個函數:

    10分鐘學習函數式Python

    我聽到您在說:“Brandon,參數在哪里?這是什么鬼東西?它看起來一點也不像一個函數?”

    嗯,這確實很令人困惑,但我可以解釋它。我們將某個東西賦值給變量square。這部分:

    10分鐘學習函數式Python

    告訴Python這是一個lambda函數,輸入被稱為x。冒號之后的任何東西都是我們對輸入所執行的操作,它返回的就是這些操作的結果。

    為了將我們的平方程序簡化成一行,我們可以這樣做:

    10分鐘學習函數式Python

    在一個lambda表達式中,所有的參數都在左邊,而我們要用它們做的事情都在右邊。沒人能否認,這有點亂。編寫只有其他函數式程序員才能閱讀的代碼是一種樂趣。另外,將一個函數轉換成一行程序是非常酷的事情。

    Python中的reduce函數

    reduce是一個函數,它將給定的函數應用于一個可迭代對象并返回一個東西。通常我們會在一個列表上進行計算,將其縮減至一個數字。Reduce看起來是這樣的:

    10分鐘學習函數式Python

    我們可以(通常也會)使用lambda表達式作為函數。

    列表的乘積是每一個數字相乘。編寫的程序是這樣:

    10分鐘學習函數式Python

    但是使用reduce我們可以這樣寫:

    10分鐘學習函數式Python

    我們得到了相同的乘積。代碼更短,并且具有函數式編程的知識,因此更簡潔。

    fileter函數

    filter函數接受一個iterable并過濾掉我們不希望存在于該iterable中的所有東西。

    filter接受一個函數和一個列表。它將該函數應用于列表中的每一項,如果該函數返回True,則不執行任何操作。如果該函數返回False,它會從該列表中刪除該項。

    語法如下:

    10分鐘學習函數式Python

    讓我們看一個小例子,沒有filter,我們會這樣寫:

    10分鐘學習函數式Python

    使用filter, 這就變成了:

    10分鐘學習函數式Python

    Python中的高階函數

    高階函數可以將函數作為參數并返回函數。一個例子是:

    10分鐘學習函數式Python

    或者第二個定義,return functions,的一個簡單例子是:

    10分鐘學習函數式Python

    高階函數使非變化變量更容易處理。如果我們所做的只是在一系列函數中傳遞數據,那么我們就不需要在任何地方存儲變量。

    Python中的所有函數都是一級對象。當一個對象具有以下特性中的一個或多個時,我們將其定義為一級對象:

    • 在運行時被創建
    • 可以被賦值給一個變量或一個數據結構中的元素
    • 作為參數被傳遞給函數
    • 作為函數的結果被返回

    因此Python中的所有函數都是一級函數,可以作為高階函數使用。

    帶函數的部分應用

    部分應用(也稱為閉包)很奇怪,但是也很酷。我們可以調用一個函數而不提供它需要的所有參數。我們來在一個例子中看一下這一點。我們想要創建一個函數,它接受兩個參數,一個基數和一個指數,然后返回基數的指數次方,就像這樣:

    10分鐘學習函數式Python

    現在我們想要一個專用的平方函數,來使用power數求出一個數的平方:

    10分鐘學習函數式Python

    這是可行的,但如果我們想要一個立方函數呢?或者一個4次方函數呢?我們能一直寫下去嗎?嗯,我們可以。但是程序員是很懶的。如果我們重復地做同一件事時,這是一個信號,表明有一種更快的方法來加快做這些事情的速度,那將允許我們不再重復地做這些事情。我們可以在這里使用部分應用。讓我們看一個使用了一個部分應用的平方函數的例子:

    10分鐘學習函數式Python

    這難道不酷嗎?我們可以通過告訴Python第二個參數是什么來只使用一個參數調用需要兩個參數的函數。

    我們還可以使用一個循環,來生成一個冪函數,其運行范圍可以從立方到1000次冪。

    10分鐘學習函數式Python

    函數式編程不是Python化

    您可能已經注意到了,我們在函數式編程中想要做的很多事情都是圍繞列表進行的。除了reduce函數和部分應用外,我們所看到的所有函數都會生成列表。Guido (Python的發明者)不喜歡Python中的函數式的東西,因為Python已經有了自己的生成列表的方法。

    如果我們在一個Python IDLE會話中輸入“import this”,我們會得到:

    10分鐘學習函數式Python

    這就是Python之禪。這是一首關于某些東西Python化意味著什么的詩。這里我們要涉及的部分是: 應該有一種——最好是只有一種——顯而易見的方法來做到它。

    在Python中,map 與 filter可以做與列表表達式(接下來討論)相同的事情。這打破了Python之禪中的一條規則,因此函數式編程的這些部分不是“Python式的”。

    另一個話題是Lambda。在Python中,lambda函數是一個普通函數。Lambda是語法糖。這兩個是等價的:

    10分鐘學習函數式Python

    一個普通函數可以做lambda函數所能做的所有事情,但反過來卻不行。一個lambda函數不能完成一個普通函數所能完成的所有工作。

    這是一個關于函數式編程為什么不能很好地適應整個Python生態系統的簡短討論。您可能已經注意到我之前提到過列表推導式,我們現在將討論它們。

    列表推導式

    之前我提到過,我們可以用列表推導式完成我們可以用map或filter所做的任何事情。這是我們要學習的關于它們的部分。

    列表推導式是在Python中生成列表的一種方式。其語法是:

    10分鐘學習函數式Python

    讓我們對一個列表中的每個數字進行平方,并以此作為一個例子:

    10分鐘學習函數式Python

    好吧,這樣我們就可以看到我們如何將一個函數應用到列表中的每一項。我們如何來應用一個filter函數呢?好吧,看看這段之前的代碼:

    10分鐘學習函數式Python

    我們可以像這樣來把它轉換成一個列表推導式:

    10分鐘學習函數式Python

    列表推導式支持像這樣的if語句。我們不需要再應用很多個函數來得到我們想要的東西了。如果我們試圖創造使用列表的機會,那么使用列表推導式可能會更清晰、更容易一些。

    如果我們想要對列表中所有小于0的數進行平方呢?那么,使用lambda、map和filter,我們會這樣寫:

    10分鐘學習函數式Python

    這有點冗長而復雜。使用一個列表推導式,它就會變成這樣:

    10分鐘學習函數式Python

    列表推導式只對列表有好處。map和filter作用于任何可迭代對象之上,那是怎么回事呢?我們可以對遇到的任何可迭代對象使用任何推導式。

    任何可迭代對象的推導式

    我們可以使用一個推導式來生成任何可迭代對象。因為我們使用的是Python 2.7,所以,我們甚至可以生成一個字典(hashmap)。

    10分鐘學習函數式Python

    如果它是一個可迭代對象,我們可以生成它。我們來看集合的最后一個例子。如果您不知道集合是什么,請查看我寫的另一篇文章(https://skerritt.blog/a-primer-on-set-theory/ )。其中的TL;DR(集合定義)是:

    • 集合是元素的列表,該列表中沒有重復的元素
    • 集合的順序無關緊要。
    10分鐘學習函數式Python

    您可能會注意到,集合具有與字典相同的花括號。Python是很聰明的。它會根據我們是否為字典提供額外的值來判斷我們寫的是一個字典推導式還是一個集合推導式。如果您想了解更多關于推導式的內容,請查看這個可視化指南。

    結論

    函數式編程是漂亮而純粹的。函數式代碼可以是簡潔的,但也可能是混亂的。您應該根據需要去使用它。

    英文原文:https://skerritt.blog/learn-functional-python-in-10-minutes/

    譯者:測試

      本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 日本高清无卡码一区二区| 国产美熟女乱又伦AV果冻传媒| 暖暖日本手机免费观看中文 | 人妻系列中文字幕精品| 久久毛片少妇高潮| 性奴sm虐辱暴力视频网站| 亚洲欧美综合精品二区| 日韩精品一区二区亚洲AV| 日本一区二区三区免费播放视频站| 国产综合久久亚洲综合| 深夜释放自己在线观看| 免费A级毛片中文字幕| 国产对白老熟女正在播放| 又大又黄又粗高潮免费| 欧美人与禽2o2o性论交| 日韩人妻系列无码专区| 高清有码国产一区二区| 国产精品青青在线观看爽香蕉| 日韩国产中文字幕精品| 亚洲另类无码一区二区三区 | 一本av高清一区二区三区| 一道本AV免费不卡播放| 欧洲一区二区中文字幕| 中文字幕无码免费久久| 久久月本道色综合久久| 天天日天天谢天天视2019天干| 人人澡人摸人人添| www久久只有这里有精品| 少妇高清一区二区免费看| 国产精品视频中文字幕| 亚洲熟妇无码一区二区三区| 国产欧美日韩亚洲一区二区三区| 国产午夜视频在线观看| 日本高清无卡码一区二区| 国产AV影片麻豆精品传媒| 国产精品IGAO视频网网址| 欧美综合人人做人人爱| 在国产线视频A在线视频| 久久久久久综合网天天 | 国产女精品视频网站免费蜜芽 | 成年美女黄网站色大片免费看|