1. map()
map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
def f(x):
return x*x
r=map(f,[1,2,3,4,5])
print(list(r))
#[1, 4, 9, 16, 25]
map()作为高阶函数,事实上它把运算规则抽象了.可以让代码更简洁;比如,把这个list所有数字转为字符串:
list(map(str,[1,2,3]))
print(a)
#['1', '2', '3']
2. reduce()
reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算.其效果就是: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]变换成整数13579:
from functools import reduce
def fn(x,y):
return x*10+y
a=reduce(fn,[1,3,5,7,9])
print(a)
把str转换为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()函数用于过滤序列。
filter()也接收一个函数和一个序列,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
例如,在一个list中,删掉偶数,只保留奇数:
def is_odd(n):
return n%2 == 1
a=filter(is_odd,[1,2,4,5,56,6,7])
print(list(a))
把一个序列中的空字符串删掉:
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求素数
计算素数的一个方法是埃氏筛法,它的算法理解起来非常简单:
首先,列出从2
开始的所有自然数,构造一个序列:
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
取序列的第一个数2
,它一定是素数,然后用2
把序列的2
的倍数筛掉:
3,4, 5,6, 7,8, 9,10, 11,12, 13,14, 15,16, 17,18, 19,20, ...
取新序列的第一个数3
,它一定是素数,然后用3
把序列的3
的倍数筛掉:
5,6, 7,8,9,10, 11,12, 13,14,15,16, 17,18, 19,20, ...
取新序列的第一个数5
,然后用5
把序列的5
的倍数筛掉:
7,8,9,10, 11,12, 13,14,15,16, 17,18, 19,20, ...
不断筛下去,就可以得到所有的素数。
#筛选函数
def not_multi(n):
return lambda x: x%n>0
#初始化的一个序列是3的倍数组成
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后重新构造序列
#打印小于1000的素数
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()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序:
sorted([36, 5, -12, 9, -21], key=abs)
#[5, 9, -12, -21, 36]
#对字符串排序,是按照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']
关键是理解key的函数是对每个元素的映射
习题:对下面的学生和分数排名
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]