久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Python中的函數(shù)式編程教程,學(xué)會(huì)用一行代碼搞定所有內(nèi)容

 山峰云繞 2021-02-15

https://m.toutiao.com/is/JEUURVQ/ 



前言

在本文中,,您將了解什么是函數(shù)范型,,以及如何在Python中使用函數(shù)式編程。在Python中,,函數(shù)式編程中的map和filter可以做與列表相同的事情,。這打破了Python的禪宗規(guī)則之一,因此函數(shù)式編程的這些部分不被認(rèn)為是“Python式的”,。但是由于函數(shù)式編程高階編程?的必經(jīng)之路,,所以我們需要了解甚至熟練掌握?。?

命令范式和函數(shù)范式

我們先對(duì)比一下編程中的命令范式兩個(gè)概念:

在命令式范式中,,您通過給計(jì)算機(jī)一個(gè)任務(wù)序列來完成任務(wù),,然后它執(zhí)行這些任務(wù)。在執(zhí)行它們時(shí),,它可以改變狀態(tài),。例如,假設(shè)你一開始把A設(shè)為5,,然后你改變A的值,,你有變量,,在這個(gè)意義上,變量內(nèi)部的值是變化的,。

在函數(shù)范型中,,你不告訴計(jì)算機(jī)要做什么,而是告訴它是什么,。例如:一個(gè)數(shù)的最大公約數(shù)是多少,,從1到n的乘積是多少,等等,。因此,,變量不能改變。一旦你設(shè)置了一個(gè)變量,,它就會(huì)一直保持這種狀態(tài)(注意,,在純函數(shù)語言中它們不被稱為變量)。所謂'副作用'(side effect),,指的是函數(shù)內(nèi)部與外部互動(dòng)(最典型的情況,,就是修改全局變量的值),產(chǎn)生運(yùn)算以外的其他結(jié)果,。函數(shù)式編程強(qiáng)調(diào)沒有'副作用',,意味著函數(shù)要保持獨(dú)立,所有功能就是返回一個(gè)新的值,,沒有其他行為,,尤其是不得修改外部變量的值。

讓我們來看一個(gè)典型Python代碼的例子:

a = 3def some_func(): global a a = 5some_func()print(a)

這段代碼的輸出是5,。在函數(shù)范型中,,改變變量是一個(gè)大禁忌,而讓函數(shù)影響它們范圍之外的東西也是一個(gè)大禁忌,。函數(shù)唯一能做的就是計(jì)算并返回結(jié)果,。

現(xiàn)在你可能會(huì)想:“沒有變量,就沒有副作用?”這有什么好處呢?”

如果一個(gè)函數(shù)使用相同的參數(shù)被調(diào)用兩次,,那么它肯定會(huì)返回相同的結(jié)果,。因?yàn)楹瘮?shù)沒有副作用,如果你正在構(gòu)建一個(gè)計(jì)算的程序,,你可以加速這個(gè)程序,。如果程序知道func(2)等于3,我們可以將其存儲(chǔ)在一個(gè)表中,。這可以防止程序在我們已經(jīng)知道答案的情況下重復(fù)運(yùn)行相同的函數(shù),。

Map

為了理解map,讓我們首先看看什么是iterables。iterable是任何可以迭代的東西,。通常這些是列表或數(shù)組,,但是Python有許多不同類型的迭代器。您甚至可以創(chuàng)建自己的對(duì)象,,這些對(duì)象可以使用Python中魔法方法進(jìn)行迭代,。這里有兩個(gè)方法:

class Counter:    def __init__(self, low, high):        # set class attributes inside the magic method __init__        # for 'inistalise'        self.current = low        self.high = high    def __iter__(self):        # first magic method to make this object iterable        return self        def __next__(self):        # second magic method        if self.current > self.high:            raise StopIteration        else:            self.current += 1            return self.current - 1

“魔法方法是python內(nèi)置方法,不需要主動(dòng)調(diào)用,,存在的目的是為了給python的解釋器進(jìn)行調(diào)用,,幾乎每個(gè)魔法方法都有一個(gè)對(duì)應(yīng)的內(nèi)置函數(shù),或者運(yùn)算符,,當(dāng)我們對(duì)這個(gè)對(duì)象使用這些函數(shù)或者運(yùn)算符時(shí)就會(huì)調(diào)用類中的對(duì)應(yīng)魔法方法,可以理解為重寫內(nèi)置函數(shù),?!?/p>

第一個(gè)神奇的方法是用“__ iter__”返回迭代對(duì)象,通常在循環(huán)開始時(shí)使用,。

如果我們運(yùn)行:

for c in Counter(38): print(c)

那么將會(huì)輸出:

345678

在Python中,,迭代器是一個(gè)對(duì)象,它只有一個(gè)簡單的魔法方法,。這意味著您可以訪問對(duì)象中的位置,,但不能遍歷對(duì)象,。有些對(duì)象將使用方法__next__,,如上面代碼中第二個(gè)例子。

現(xiàn)在我們知道了什么是可迭代對(duì)象,,讓我們回到map函數(shù),。map函數(shù)允許我們將一個(gè)函數(shù)應(yīng)用到iterable中的每個(gè)項(xiàng)。通常,,我們希望對(duì)列表中的每一項(xiàng)都應(yīng)用一個(gè)函數(shù),,但是要知道對(duì)于大多數(shù)迭代器來說都是可能的。Map接受兩個(gè)輸入,,即要應(yīng)用的函數(shù)和可迭代的對(duì)象:

map(functioniterable)

假設(shè)我們有一個(gè)列表:

[1, 2, 3, 4, 5]

我們希望將列表中的每一個(gè)數(shù)字進(jìn)行平方,,那么可以這么寫代碼:

x = [1, 2, 3, 4, 5]def square(num): return num*numprint(list(map(square, x)))

Python中的函數(shù)是惰性的。如果我們代碼中不包含“l(fā)ist()”,,函數(shù)將存儲(chǔ)迭代的定義,,而不是一個(gè)列表。我們需要顯式地告訴Python“將這個(gè)轉(zhuǎn)換為一個(gè)列表”,,以便我們使用它,。

現(xiàn)在寫一個(gè)像“square(num)”這樣的普通函數(shù)很好,但是它看起來不太對(duì),。我們必須定義一個(gè)完整的函數(shù)才能在map中使用一次?我們可以使用lambda(匿名)函數(shù)在map中定義一個(gè)函數(shù),。

lambda 表達(dá)式

lambda表達(dá)式是一個(gè)單行函數(shù),。舉個(gè)例子,這個(gè)lambda表達(dá)式對(duì)給定的一個(gè)數(shù)字求平方:

square = lambda x: x * x

運(yùn)行程序:

>>> square(3)9

告訴Python這是一個(gè)lambda函數(shù),,輸入被稱為x,,冒號(hào)后面的內(nèi)容就是你對(duì)輸入的操作,它會(huì)自動(dòng)返回結(jié)果,。

現(xiàn)在我們可以將上面的程序簡化:

x = [1, 2, 3, 4, 5]print(list(map(lambda num: num * num, x)))

Reduce

Reduce是一個(gè)函數(shù),,它把一個(gè)可迭代的東西變成一個(gè)東西。通常,,您在一個(gè)列表上執(zhí)行計(jì)算以將其縮減為一個(gè)數(shù)字,。Reduce是這樣的:

reduce(functionlist)

我們可以(通常也會(huì))使用lambda表達(dá)式作為函數(shù)。

列表的乘積是每一個(gè)單獨(dú)的數(shù)字相乘,。要做到這一點(diǎn),,你可以:

product = 1x = [1, 2, 3, 4]for num in x:    product = product * num

但是使用reduce你可以這樣寫:

from functools import reduceproduct = reduce((lambda x, y: x * y),[1234])

Filter

filter函數(shù)接受一個(gè)iterable并過濾掉在該iterable中不需要的所有東西。

filter通常接受一個(gè)函數(shù)和一個(gè)列表,。它將函數(shù)應(yīng)用于列表中的每一項(xiàng),,如果該函數(shù)返回True,則不執(zhí)行任何操作,。如果返回False,,則從列表中刪除該項(xiàng)目。

語法如下:

filter(functionlist)

讓我們看看一個(gè)小例子,,沒有過濾器,,我們會(huì)寫:

x = range(-5, 5)new_list = []for num in x: if num < 0: new_list.append(num)

有了過濾器,這就變成:

x = range(-5, 5)all_less_than_zero = list(filter(lambda num: num < 0, x))

高階函數(shù)

高階函數(shù)可以將函數(shù)作為參數(shù)并返回函數(shù),。一個(gè)非常簡單的例子如下:

def summation(nums): return sum(nums)def action(func, numbers): return func(numbers)print(action(summation, [1, 2, 3]))

partial application

部分應(yīng)用程序(也稱為閉包)有點(diǎn)奇怪,,但是非常酷,。您可以調(diào)用一個(gè)函數(shù)而不提供它需要的所有參數(shù),。我們來看一個(gè)例子。我們想要?jiǎng)?chuàng)建一個(gè)函數(shù),,它有兩個(gè)參數(shù),,一個(gè)底數(shù)和一個(gè)指數(shù),并返回底數(shù)的指數(shù)次方,,就像這樣:

def power(base, exponent):  return base ** exponent

現(xiàn)在我們想要一個(gè)專門的平方函數(shù),,用冪函數(shù)求出一個(gè)數(shù)的平方:

def square(base): return power(base, 2)

這是可行的,但如果我們想要一個(gè)立方體函數(shù)呢?或者是函數(shù)的4次方?我們能一直寫下去嗎?嗯,你可以,。但是程序員很懶,。如果你一遍又一遍地重復(fù)同樣的事情,這是一個(gè)信號(hào),表明有一種更快的方法可以加快速度,,讓你不再重復(fù),。我們可以在這里使用部分應(yīng)用程序。讓我們看一個(gè)例子的平方函數(shù)使用部分應(yīng)用程序:

from functools import partial?square = partial(power, exponent=2)print(square(2))

這是不是很酷!我們可以調(diào)用需要兩個(gè)參數(shù)的函數(shù),,只需使用一個(gè)參數(shù)就可以告訴Python第二個(gè)參數(shù)是什么,。

參考:https:///hackernoon/learn-functional-python-in-10-minutes-to-2d1651dece6f

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請遵守用戶 評(píng)論公約

    類似文章 更多