1. map()
map()函數(shù)接收兩個(gè)參數(shù),一個(gè)是函數(shù),一個(gè)是Iterable张吉,map將傳入的函數(shù)依次作用到序列的每個(gè)元素,并把結(jié)果作為新的Iterator返回催植。
def f(x):
return x*x
r=map(f,[1,2,3,4,5])
print(list(r))
#[1, 4, 9, 16, 25]
map()作為高階函數(shù)肮蛹,事實(shí)上它把運(yùn)算規(guī)則抽象了.可以讓代碼更簡(jiǎn)潔;比如查邢,把這個(gè)list所有數(shù)字轉(zhuǎn)為字符串:
list(map(str,[1,2,3]))
print(a)
#['1', '2', '3']
2. reduce()
reduce把一個(gè)函數(shù)作用在一個(gè)序列[x1, x2, x3, ...]上蔗崎,這個(gè)函數(shù)必須接收兩個(gè)參數(shù),reduce把結(jié)果繼續(xù)和序列的下一個(gè)元素做累積計(jì)算.其效果就是:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
from functools import reduce
def add(x,y):
return x+y
a=reduce(add,[1,2,4])
print(a)
#7
把序列[1, 3, 5, 7, 9]變換成整數(shù)13579:
from functools import reduce
def fn(x,y):
return x*10+y
a=reduce(fn,[1,3,5,7,9])
print(a)
把str轉(zhuǎn)換為int:
from functools import reduce
def char2num(s):
digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
return digits[s]
def fn(x,y):
return x*10+y
a=reduce(fn,map(char2num,'13579'))
print(a)
整理下:
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 DIGITS[s]
return reduce(fn, map(char2num, s))
或者用lambda
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 char2num(s):
return DIGITS[s]
def str2int(s):
return reduce(lambda x, y: x * 10 + y, map(char2num, s))
3. filter()
filter()函數(shù)用于過濾序列扰藕。
filter()也接收一個(gè)函數(shù)和一個(gè)序列缓苛,filter()把傳入的函數(shù)依次作用于每個(gè)元素,然后根據(jù)返回值是True還是False決定保留還是丟棄該元素。
例如未桥,在一個(gè)list中笔刹,刪掉偶數(shù),只保留奇數(shù):
def is_odd(n):
return n%2 == 1
a=filter(is_odd,[1,2,4,5,56,6,7])
print(list(a))
把一個(gè)序列中的空字符串刪掉:
def not_empty(s):
return s and s.strip()
a=list(filter(not_empty, ['A', '', 'B', None, 'C', ' sdf s ']))
print(a)
#['A', 'B', 'C', ' sdf s ']
說明:None 冬耿、空字符串的bool值為0舌菜,但是有空格的字符bool為1.所以要使用strip方法把這種字符也刪掉。
用filter求素?cái)?shù)
計(jì)算素?cái)?shù)的一個(gè)方法是埃氏篩法亦镶,它的算法理解起來非常簡(jiǎn)單:
首先日月,列出從2
開始的所有自然數(shù),構(gòu)造一個(gè)序列:
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
取序列的第一個(gè)數(shù)2
缤骨,它一定是素?cái)?shù)爱咬,然后用2
把序列的2
的倍數(shù)篩掉:
3,4, 5,6, 7,8, 9,10, 11,12, 13,14, 15,16, 17,18, 19,20, ...
取新序列的第一個(gè)數(shù)3
,它一定是素?cái)?shù)绊起,然后用3
把序列的3
的倍數(shù)篩掉:
5,6, 7,8,9,10, 11,12, 13,14,15,16, 17,18, 19,20, ...
取新序列的第一個(gè)數(shù)5
精拟,然后用5
把序列的5
的倍數(shù)篩掉:
7,8,9,10, 11,12, 13,14,15,16, 17,18, 19,20, ...
不斷篩下去,就可以得到所有的素?cái)?shù)虱歪。
#篩選函數(shù)
def not_multi(n):
return lambda x: x%n>0
#初始化的一個(gè)序列是3的倍數(shù)組成
def is_iter():
n = 1
while True:
n = n+2
yield n
def prime():
yield 2
it = is_iter()
while True:
n = next(it)
yield n
it = filter(not_multi(n),it)#取走3后重新構(gòu)造序列
#打印小于1000的素?cái)?shù)
for n in prime():
if n < 1000:
print(n)
else:
break
4. sorted()
sorted([36, 5, -12, 9, -21])
#[-21, -12, 5, 9, 36]
sorted()函數(shù)也是一個(gè)高階函數(shù)蜂绎,它還可以接收一個(gè)key函數(shù)來實(shí)現(xiàn)自定義的排序,例如按絕對(duì)值大小排序:
sorted([36, 5, -12, 9, -21], key=abs)
#[5, 9, -12, -21, 36]
#對(duì)字符串排序笋鄙,是按照ASCII的大小比較的.'Z' < 'a'
sorted(['bob', 'about', 'Zoo', 'Credit'])
#['Credit', 'Zoo', 'about', 'bob']
sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
#['about', 'bob', 'Credit', 'Zoo']
sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
#['Zoo', 'Credit', 'bob', 'about']
關(guān)鍵是理解key的函數(shù)是對(duì)每個(gè)元素的映射
習(xí)題:對(duì)下面的學(xué)生和分?jǐn)?shù)排名
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_score(t):
return t[1]
def by_name(t):
return t[0].lower()
print(sorted(L,key=by_score))
print(sorted(L,key=by_name))
print(sorted(L,key=lambda x:x[1]))
#[('Bart', 66), ('Bob', 75), ('Lisa', 88), ('Adam', 92)]
#[('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)]
#[('Bart', 66), ('Bob', 75), ('Lisa', 88), ('Adam', 92)]
#[Finished in 0.2s]