map()
map()
函數(shù)接受兩個參數(shù),一個是函數(shù),一個是可迭代對象(Iterable
)
,
map
將傳入的函數(shù)依次作用到可迭代對象的每一個元素,并把結(jié)果作為迭代器(Iterator)
返回。
舉例說明,有一個函數(shù)
f(x)=x^2
,要把這個函數(shù)作用到一個list
[1,2,3,4,5,6,7,8,9]
上:
運(yùn)用簡單的循環(huán)可以實現(xiàn):
>>>
def
f(x):...
return x * x
...
L = []
for n
in [1, 2, 3, 4, 5, 6, 7, 8, 9]:
L.append(f(n))
print(L)
運(yùn)用高階函數(shù)
map()
:
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
結(jié)果
r
是一個迭代器,迭代器是惰性序列,通過
list()
函數(shù)讓它把整個序列都計算出來并返回一個
list
。
如果要把這個list
所有數(shù)字轉(zhuǎn)為字符串利用
map()
就簡單了:
>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
小練習(xí):利用
map()
函數(shù),把用戶輸入的不規(guī)范的英文名字變?yōu)槭鬃帜复髮懫渌懙囊?guī)范名字。輸入
['adam', 'LISA', 'barT'] ,
輸出
['Adam', 'Lisa', 'Bart']
def
normalize(name):
return name.capitalize()
l1=["adam","LISA","barT"]
l2=list(map(normalize,l1))
print(l2)
reduce()
reduce()
函數(shù)也是接受兩個參數(shù),一個是函數(shù),一個是可迭代對象,
reduce
將傳入的函數(shù)作用到可迭代對象的每個元素的結(jié)果做累計計算。然后將最終結(jié)果返回。
效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
舉例說明,將序列
[1,2,3,4,5]
變換成整數(shù)
12345
:
>>>
from functools
import reduce>>>
def
fn(x, y):...
return x * 10 + y
...>>> reduce(fn, [1, 2, 3, 4, 5])12345
小練習(xí):編寫一個
prod()
函數(shù),可以接受一個
list
并利用
reduce
求積:
from functools
import reduce
def
pro (x,y):
return x * y
def
prod(L):
return reduce(pro,L)
print(prod([1,3,5,7]))
map()
和
reduce()
綜合練習(xí):編寫
str2float
函數(shù),把字符串
'123.456'
轉(zhuǎn)換成浮點型
123.456
CHAR_TO_FLOAT = {
'0': 0,'1': 1,'2': 2,'3': 3,'4': 4,'5': 5,'6': 6,'7': 7,'8': 8,'9': 9, '.': -1
}
def
str2float(s):
nums = map(
lambda ch:CHAR_TO_FLOAT[ch],s)
point = 0
def
to_float(f,n):
nonlocal point
if n==-1:
point =1
return f
if point ==0:
return f*10+n
else:
point =point *10
return f + n/point
return reduce(to_float,nums,0)#
第三個參數(shù)
0
是初始值,對應(yīng)
to_float
中
f
filter()
filter()
函數(shù)用于過濾序列,
filter()
也接受一個函數(shù)和一個序列,
filter()
把傳入的函數(shù)依次作用于每個元素,然后根據(jù)返回值是
True
還是
False
決定保留還是丟棄該元素。
舉例說明,刪除list
中的偶數(shù)
:
def
is_odd(n):
return n % 2 == 1
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))#
結(jié)果
: [1, 5, 9, 15]
小練習(xí):用
filter()
求素數(shù)
計算
素數(shù)
的一個方法是
埃氏篩法
,它的算法理解起來非常簡單:
首先,列出從2
開始的所有自然數(shù),構(gòu)造一個序列:
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
取序列的第一個數(shù)2
,它一定是素數(shù),然后用
2
把序列的
2
的倍數(shù)篩掉:
3,
4
, 5,
6
, 7,
8
, 9,
10
, 11,
12
, 13,
14
, 15,
16
, 17,
18
, 19,
20
, ...
取新序列的第一個數(shù)3
,它一定是素數(shù),然后用
3
把序列的
3
的倍數(shù)篩掉:
5,
6
, 7,
8
,
9
,
10
, 11,
12
, 13,
14
,
15
,
16
, 17,
18
, 19,
20
, ...
取新序列的第一個數(shù)5
,然后用
5
把序列的
5
的倍數(shù)篩掉:
7,
8
,
9
,
10
, 11,
12
, 13,
14
,
15
,
16
, 17,
18
, 19,
20
, ...
不斷篩下去,就可以得到所有的素數(shù)。
用Python
實現(xiàn)這個算法,先構(gòu)造一個從
3
開始的期數(shù)數(shù)列:
def
_odd_iter():
n = 1
while
True:
n = n + 2
yield n#
這是一個生成器,并且是一個無線序列
定義一個篩選函數(shù):
def
_not_divisible(n):
return
lambda x: x % n > 0
定義一個生成器不斷返回下一個素數(shù):
def
primes():
yield 2
it = _odd_iter() #
初始序列
while
True:
n = next(it) #
返回序列的第一個數(shù)
yield n
it = filter(_not_divisible(n), it) #
構(gòu)造新序列
打印100
以內(nèi)素數(shù):
for n
in primes():
if n < 100:
print(n)
else:
break
sorted()
python
內(nèi)置的
sorted()
函數(shù)可以對list
進(jìn)行排序:
>>>
sorted([36, 5, -12, 9, -21])[-21, -12, 5, 9, 36]
sorted()
函數(shù)也是一個高階函數(shù),還可以接受一個
key
函數(shù)來實現(xiàn)自定義排序:
>>>
sorted([36, 5, -12, 9, -21], key=abs)[5, 9, -12, -21, 36]
key
指定的函數(shù)將作用于list
的每一個元素上,并根據(jù)
key
函數(shù)返回的結(jié)果進(jìn)行排序.
默認(rèn)情況下,對字符串排序,是按照ASCII
的大小比較的,由于
'Z' < 'a'
,結(jié)果,大寫字母
Z
會排在小寫字母
a
的前面。如果想忽略大小寫可都轉(zhuǎn)換成小寫來比較:
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
['about', 'bob', 'Credit', 'Zoo']
要進(jìn)行反向排序,不必改動key
函數(shù),可以傳入第三個參數(shù)
reverse=True
:
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
['Zoo', 'Credit', 'bob', 'about']
小練習(xí):假設(shè)我們用一組tuple
表示學(xué)生名字和成績:
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
。用sorted()
對上述列表分別按
c
成績從高到低排序:
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def
by_score(t):
for i
in t:
return t[1]
L2=sorted(L,key= by_score)
print(L2)
運(yùn)用匿名函數(shù)更簡潔:
L2=sorted(
L,key=lambda t:t[1])
print(
L2)
來源:簡書