map()函數(shù)
map()是 Python 內(nèi)置的高階函數(shù),它接收一個函數(shù) f 和一個 list,并通過把函數(shù) f 依次作用在 list 的每個元素上,得到一個新的 list 并返回。
例如,對于list [1, 2, 3, 4, 5, 6, 7, 8, 9]
如果希望把list的每個元素都作平方,就可以用map()函數(shù):
因此,我們只需要傳入函數(shù)f(x)=x*x,就可以利用map()函數(shù)完成這個計算:
def f(x):
return x*x
print map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
輸出結(jié)果:
[1, 4, 9, 10, 25, 36, 49, 64, 81]
注意:map()函數(shù)不改變原有的 list,而是返回一個新的 list。
利用map()函數(shù),可以把一個 list 轉(zhuǎn)換為另一個 list,只需要傳入轉(zhuǎn)換函數(shù)。
由于list包含的元素可以是任何類型,因此,map() 不僅僅可以處理只包含數(shù)值的 list,事實上它可以處理包含任意類型的 list,只要傳入的函數(shù)f可以處理這種數(shù)據(jù)類型。
假設用戶輸入的英文名字不規(guī)范,沒有按照首字母大寫,后續(xù)字母小寫的規(guī)則,請利用map()函數(shù),把一個list(包含若干不規(guī)范的英文名字)變成一個包含規(guī)范英文名字的list:
輸入:['adam', 'LISA', 'barT']
輸出:['Adam', 'Lisa', 'Bart']
def format_name(s):
return s[0].upper()+s[1:].lower()
print map(format_name, ['adam', 'LISA', 'barT'])
#['Adam', 'Lisa', 'Bart']
reduce()函數(shù)
reduce()函數(shù)也是Python內(nèi)置的一個高階函數(shù)。reduce()函數(shù)接收的參數(shù)和 map()類似,一個函數(shù) f,一個list,但行為和 map()不同,reduce()傳入的函數(shù) f 必須接收兩個參數(shù),reduce()對list的每個元素反復調(diào)用函數(shù)f,并返回最終結(jié)果值。
例如,編寫一個f函數(shù),接收x和y,返回x和y的和:
def f(x, y):
return x + y
調(diào)用 reduce(f, [1, 3, 5, 7, 9])時,reduce函數(shù)將做如下計算:
先計算頭兩個元素:f(1, 3),結(jié)果為4;
再把結(jié)果和第3個元素計算:f(4, 5),結(jié)果為9;
再把結(jié)果和第4個元素計算:f(9, 7),結(jié)果為16;
再把結(jié)果和第5個元素計算:f(16, 9),結(jié)果為25;
由于沒有更多的元素了,計算結(jié)束,返回結(jié)果25。
上述計算實際上是對 list 的所有元素求和。雖然Python內(nèi)置了求和函數(shù)sum(),但是,利用reduce()求和也很簡單。
reduce()還可以接收第3個可選參數(shù),作為計算的初始值。如果把初始值設為100,計算:
reduce(f, [1, 3, 5, 7, 9], 100)
結(jié)果將變?yōu)?25,因為第一輪計算是:
計算初始值和第一個元素:f(100, 1),結(jié)果為101。
Python內(nèi)置了求和函數(shù)sum(),但沒有求積的函數(shù),求2,4,5,7,12的乘積,可以使用reduce()函數(shù):
def prod(x, y):
return x*y
print reduce(prod, [2, 4, 5, 7, 12])
#3360
filter()
filter()函數(shù)是 Python 內(nèi)置的另一個有用的高階函數(shù),filter()函數(shù)接收一個函數(shù) f 和一個list,這個函數(shù) f 的作用是對每個元素進行判斷,返回 True或 False,filter()根據(jù)判斷結(jié)果自動過濾掉不符合條件的元素,返回由符合條件元素組成的新list。
例如,要從一個list [1, 4, 6, 7, 9, 12, 17]中刪除偶數(shù),保留奇數(shù),首先,要編寫一個判斷奇數(shù)的函數(shù):
def is_odd(x):
return x % 2 == 1
然后,利用filter()過濾掉偶數(shù):
filter(is_odd, [1, 4, 6, 7, 9, 12, 17])
結(jié)果:[1, 7, 9, 17]
利用filter(),可以完成很多有用的功能,例如,刪除 None 或者空字符串:
def is_not_empty(s):
return s and len(s.strip()) > 0
filter(is_not_empty, ['test', None, '', 'str', ' ', 'END'])
結(jié)果:['test', 'str', 'END']
注意: s.strip(rm) 刪除 s 字符串中開頭、結(jié)尾處的 rm 序列的字符。
當rm為空時,默認刪除空白符(包括'\n', '\r', '\t', ' '),如下:
a = ' 123'
a.strip()
結(jié)果: '123'
a='\t\t123\r\n'
a.strip()
結(jié)果:'123'
sorted()
Python內(nèi)置的 sorted()函數(shù)可對list進行排序:
>>>sorted([36, 5, 12, 9, 21])
[5, 9, 12, 21, 36]
但 sorted()也是一個高階函數(shù),它可以接收一個比較函數(shù)來實現(xiàn)自定義排序,比較函數(shù)的定義是,傳入兩個待比較的元素 x, y,如果 x 應該排在 y 的前面,返回 -1,如果 x 應該排在 y 的后面,返回 1。如果 x 和 y 相等,返回 0。
因此,如果我們要實現(xiàn)倒序排序,只需要編寫一個reversed_cmp函數(shù):
def reversed_cmp(x, y):
if x > y:
return -1
if x < y:
return 1
return 0
這樣,調(diào)用 sorted() 并傳入 reversed_cmp 就可以實現(xiàn)倒序排序:
>>> sorted([36, 5, 12, 9, 21], reversed_cmp)
[36, 21, 12, 9, 5]
sorted()也可以對字符串進行排序,字符串默認按照ASCII大小來比較:
>>> sorted(['bob', 'about', 'Zoo', 'Credit'])
['Credit', 'Zoo', 'about', 'bob']
'Zoo'排在'about'之前是因為'Z'的ASCII碼比'a'小。
Python的字符串比較與Java類似,用cmp()方法來比較兩個對象,相等返回 0 ,前大于后,返回 1,小于返回 -1.
對字符串排序時,有時候忽略大小寫排序更符合習慣。因此,可以這樣:
def cmp_ignore_case(s1, s2):
return cmp(s1.lower(),s2.lower())
print sorted(['bob', 'about', 'Zoo', 'Credit'],cmp_ignore_case)
#['about', 'bob', 'Credit', 'Zoo']