1. 程式人生 > >函數語言程式設計與高階函式

函數語言程式設計與高階函式

初步接觸了以下幾種高階函式,還用的不是很熟練。

1、map(): 這個函式接受兩個引數: ‘map(function, sequence)’ 第一個必需引數是一個編輯好的函式,第二個引數是一個序列,map()的作用是按照序列的順序依次對元素使用function。個人理解就類似於批處理吧,比如由一大堆名字組成的序列,其中沒有規範的使用大小寫,那我們可以定義一個修改函式,並依次對列表元素使用。以下是廖雪峰大大布置的作業:

思路:1、用map()函式來處理列表。所以

map(func, ['aDam', 'BerT', 'JERRY'])

2、定義func函式,輸入一個字串,輸出成為首字母大寫,其餘小寫的字串。

3、使用lower()函式,在此我遇到了一個錯誤,以為lower()還屬於半自動化的函式,比如一個指令小寫一個字母,因此我用了迭代的方法去使用這個函式:

def func(word):
     for s in word:
        return s.lower()


結果:

>>>func('Adam')
'a'


一時間沒想通,後來在互動式介面中發現lower()可以直接將一整個字串改寫為小寫。囧

於是修改後的函式:

def func(word):
    return word.lower()

這樣就能得到全是小寫的string。用map函式套用上,得到三個小寫的string,想再定義一個函式,使所有字串的首字母大寫。

想到字串也是一個列表,用string[0]可以定位到第一個字母,但是回想起之前所學的slice操作,發現可以減少不少步驟:

def func(s):
    return s[0].upper() + s[1:].lower()


於是這樣就在一行裡完成了這個函式。(其實這一步參考了大家的想法。。sad。。思維還是比較死板的,也反映出了基礎打得不紮實)

接著套用map函式就可以完成作業了。

4、質數的判定:虛擬碼:

n是否是大於1 的正整數--T/F

大於1則生成2~n-1的列表a

迭代,若在a中有一個數使得n能被整除,則不是質數。

def is_prime(x):
    if type(x) != int or x <= 1:
        return False
    else:
        for n in range(2, x):
           if (x % n) == 0:
               return False
               break
        else:
            return True
        
雖然練過很多次了還是很艱難的寫出來,主要是如何判斷質數這裡想了很久,數學也是很差=。= 繼續努力吧 5、filter(func, sequence)    篩選函式, 對序列使用函式,返回true的留下返回false的拋棄 6、6、6、6、6、6、 閉包是什麼鬼啊。。。。。s一頭霧水, 首先:廖雪峰大大用返回值來引入:
def sum(*args):      #輸入多個變數
    ax = 0
    for n in args:      #迭代輸入的變數
         ax = ax + n   #依次相加求和
    return ax

這裡的返回值是ax 是一個整數,代表著前面*args的總和 接下來老師說 “如果返回的是函式呢?”
def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
             ax = ax + n
        return ax
    return sum

到這裡已經開始有點迷惑了 來一步步分析: 互動式介面中呼叫lazy_sum(1,2,3,4,5) 返回一個函式<function ...............> 若要得到其值 要先將lazy_sum賦值給一個變數 比如F 再用F() 呼叫 這裡就不是很懂,一點愚見“一開始定義了兩個函式,所以要經過兩次呼叫才能得出結果“ 這是初步的一種記憶的方法 接著看 #要注意的問題 返回的函式並沒有立即執行,要經過F()才執行。 另一個開始不懂的例子:
def count():
     fs = []
     for i in range(1, 4):
         def f():
              return  i*i
         fs.append(f)
     return fs

f1, f2, f3 = count()

第一步 定義count()函式, 呼叫函式時,內部先建立一個空列表,接著生成一個從1-3的列表進行迭代 第二步 列表中取出 1 ,呼叫f() 返回1*1 (函式1),並將此函式新增到fs這個列表裡 第三步 列表中取出 2 ,呼叫f() 返回2*2 (函式2),並將此函式新增到fs這個列表裡 第四步 列表中……………………………………………………………………………… 第五步 迭代完成 返回一個含有3個元素的列表 fs ,並且元素是函式f() 第六步 注意此時返回的函式並沒有執行,要再次經過呼叫,而且呼叫的內容是i*i 第七步 注意之前的i是正在迭代的 從1 - 3 所以此時的i=3 第八步 將fs中的三個函式分別賦值給f1, f2, f3  再依次呼叫f() 第九步 發現結果全都是9 (3*3) 果然列出來了就是想清楚了 nice!

再來一波: 避免在返回的函式裡(f())引用迴圈變數,或者後續會發生的變數,比如剛才的i*i

def count():
    fs = []
    for i in range(1, 4):
        def f(j):
            def g():
                return j*j
            return g
        fs.append(f(i))
    return fs

f1, f2, f3 = count()

第一步 定義count函式,函式中有一個空列表fs 生成1-3的列表。

第二部 定義f函式,引數是j ,在f函式內部定義函式g 返回j*j, 再將此函式返回f函式,此時函式f(j)返回一個函式j*j(g).

第三步 向fs列表中新增 引數是i的f(), 此時j=i 代入運算返回 g1=i*i(此時i = 1) 所以g1 = 1*1

第四步 向fs列表中新增  引數是i的f(), 此時j=i 帶入運算返回 g2 = i * i (此時 i=2 )所以g2 = 2 * 2

第五步 同上

第六步 迭代完成後fs中有三個f() 分別為g1 g2 g3 要再次進行呼叫才能得出結果。分別賦值給f123 3個變數

第七步 執行 得到結果 不受i的影響,因為j取值是i是固定的 隨後i改變時j不變 因此得以儲存

弄了這麼多還沒有觸及到閉包 囧。。。

教程說 “在外函式中定義了內函式,並且 內部函式可以引用外部函式的引數和區域性變數。當外層函式返回內層函式時,相關引數和變數都儲存在返回的函式(內函式)中,這種稱為閉包的程式結構 巴拉巴拉” 似乎懂一點,

先拿它的作用來湊個數 [轉載 來自  ] what? 為啥連超連結和下面的url都不能用複製 我都寫了轉載。。