Python廖雪峯教程學習筆記:Day6

前言

養成一個好的習慣只需要堅持21天,Day6

函數式編程

  • 高階函數
  1. map/reduce
  2. filter
  3. sorted

高階函數

變量可以指向函數,如 x = abs(-10)
函數本身可以賦值給變量,如f = abs f(-10)
既然變量可以指向函數,函數的參數能接收變量,那麼一個函數就可以接收另一個函數作爲參數,這種函數就稱之爲高階函數。例如:

def add(x,y,f):
	return f(x)+f(y)

在這裏插入圖片描述

  • map
    map()函數接收兩個參數,一個是函數,一個是Iterable,map將傳入的函數依次作用到序列的每個元素,並把結果作爲新的Iterator返回。
def f(x):
	return x*x
r=map(f,[1,2,3,4,5,6,7,8,9])
list(r)

在這裏插入圖片描述
map()傳入的第一個參數是f,即函數對象本身,結果r是一個Iterator(迭代器),Iterator是惰性序列,因此通過list()函數讓它把整個序列都計算出來並返回一個list。
map()作爲高階函數,把計算規則抽象化,例如可以通過一句話把list中所有數字轉化爲字符串:
在這裏插入圖片描述

  • reduce
    reduce把一個函數作用在一個序列[x1, x2, x3, ...]上,這個函數必須接收兩個參數,reduce把結果繼續和序列的下一個元素做累積計算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

(1)把一個序列[1, 3, 5, 7, 9]變換成整數13579

from functools import reduce
def fn(x,y):
    return x*10+y

在這裏插入圖片描述
(2)把一個str轉換成int

from functools import reduce

DIGITS = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}

def str2int(s):
	def fn(x,y):
		return x*10+y
	def char2num(s):
		return DIGHTS[s]
	return reduce(fn,map(char2num,s))

運行結果:
在這裏插入圖片描述

def normalize(name):
    name = name[0].upper() + name[1:].lower()
    return name
L1 = ['adam','LISA','barT']
L2 = list(map(normalize,L1))
print(L2)

運行結果:
在這裏插入圖片描述
練習
編寫一個prod()函數,可以接受一個list並利用reduce()求積:

def prod(L):
    def fn(x,y):
        return x*y
    return reduce(fn,L)
print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9]))
if prod([3, 5, 7, 9]) == 945:
    print('測試成功!')
else:
    print('測試失敗!')

運行結果:
在這裏插入圖片描述
利用map和reduce編寫一個str2float函數,把字符串’123.456’轉換成浮點數123.456:

from functools import reduce

DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}


def str2float(s):
    def fn(x,y):
        return x*10+y
    def char2num(s):
        return DIGITS[s]
    n = s.index('.')
    s1 = list(map(char2num,s[:n]))
    s2 = list(map(char2num,s[n+1:]))
    return reduce(fn,s1)+reduce(fn,s2)/10**len(s2)

在這裏插入圖片描述

  • filter

Python 內建的filter()函數用於過濾系列,和map()函數類似,filter()函數也接受一個函數的一個序列。例如,刪除一個list中的偶數,只保留奇數:

def is_odd(n):
	return n%2 == 1
list(filter(is_odd,[1,2,3,4,5,6,7,8,9]))
#運行結果 [1, 3, 5, 7, 9]

練習
回數是指從左向右讀和從右向左讀都是一樣的數,例如12321,909。請利用filter()篩選出回數:

def is_palindrome(n):
	s = str(n)          #把整數轉化成字符串
	return s == s[::-1] #利用切片把整個字符串反轉再進行比較
output = filter(is_palindrome, range(1, 1000))
print('1~1000:', list(output))
if list(filter(is_palindrome, range(1, 200))) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191]:
    print('測試成功!')
else:
    print('測試失敗!')

在這裏插入圖片描述

  • sorted
    Python內置的sorted()函數可以對list進行排序:
L = [-10,4,3,89,7]
sorted(L)
#運行結果爲[-10, 3, 4, 7, 89]

此外,sorted()函數也是一個高階函數,它還可以接收一個key函數來實現自定義的排序,例如按絕對值大小排序:

L = [-10,4,3,89,7]
sorted(L,key=abs)
#[3, 4, 7, -10, 89]

默認情況下,對字符串進行排序時是按照ASCII的大小比較的,小寫字母的ASCII碼比大寫字母大:

sorted(['Tom','bob','Mary','Jack'])
#['Jack', 'Mary', 'Tom', 'bob']

若想在對字符串排序的時候,忽略大小寫,可以傳入key值:

sorted(['Tom','bob','Mary','Jack'],key=str.lower)
#['bob', 'Jack', 'Mary', 'Tom']

要進行反向排序,可以傳入第三個參數reverse=True

sorted(['Tom','bob','Mary','Jack'],key=str.lower,reverse=True)
#['Tom', 'Mary', 'Jack', 'bob']

練習
假設我們用一組tuple表示學生名字和成績:L = [(‘Bob’, 75), (‘Adam’, 92), (‘Bart’, 66), (‘Lisa’, 88)]
請用sorted()對上述列表分別按名字排序:

L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_name(t):
	return t[0].lower()
L2 = sorted(L, key=by_name)
print(L2)
#[('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)]

再按成績從高到低排序:

def by_scort(t):
    return t[1]
L=[('Bob',75),('Adam',92),('Bart',66),('Lisa',88)]
L1=sorted(L,key=by_scort,reverse=True)
print(L1)   
#[('Adam', 92), ('Lisa', 88), ('Bob', 75), ('Bart', 66)]
發佈了9 篇原創文章 · 獲贊 20 · 訪問量 1634
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章