一、高阶函数基础
(一)、变量可以指向函数
abs
<function abs(x, /)>
abs(-10)
10
x = abs(-10)
print(x)
10
f = abs
print(f)
<built-in function abs>
# 变量f指向了一个函数
# f = abs
# print(f(-10))
(二)、函数名也是变量
# abs指向数值后,就无法
# abs = 10
# abs(-10)
(三)、传入函数
变量可以指向函数,函数的参数能接受变量,那么一个函数的变量就能指向另一个函数。这种函数即为高阶函数。
def add(x,y,f):
return f(x) + f(y)
add(-5,5,abs)
10
二、Map函数
map函数接受两个参数,一个是函数,一个是Iterable(可迭代对象),map将传入的函数依次作用于序列中的每个元素,并把结果作为新的Iterator返回。
def f(x):
return x * x
r = map(f,[1,2,3,4,5,6,7,8,9,10])
list(r)
# 输出结果:[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
上面这个例子也可以使用循环实现:
def f(x):
return x * x
L =[]
for i in range(1,11):
L.append(f(i))
print(L)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
但用循环的缺点在于稍微有些抽象,不如直接用map函数形象。
三、reduce函数
reduce函数把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce()函数把结果和序列的下一个元素做累计计算。
from functools import reduce
def add(x,y):
return x + y
reduce(add, [1,3,5,7])
16
将序列[1,3,5,7]变换为整数1357
from functools import reduce
def str2int(x,y):
return x *10 + y
reduce(str2int, [1,3,5,7])
1357
将str
转换为int
函数
from functools import reduce
def str2int(x,y):
return x *10 + y
def convert(i):
digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
return digits[i]
reduce(str2int, map(convert, '1357'))
1357
整理为一个str2int函数:
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(n):
def s2t(x,y):
return x *10 + y
def convert(n):
return digits[n]
return reduce(s2t, map(convert, n))
str2int('255')
255
使用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 convert(i):
return digits[i]
def str2int(i):
return reduce(lambda x, y: x * 10 + y, map(convert, i)) #使用lambda x, y: x * 10 + y替换了str2int(n)函数
str2int('2566')
2566
利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']:
def normalize(names):
return names[0].upper() + names[1:].lower()
names = ['adam', 'LISA', 'barT']
list(map(normalize, names))
['Adam', 'Lisa', 'Bart']
请编写一个prod()函数,可以接受一个list并利用reduce()求积:
# def prod(*num):
# n = 1
# for i in L:
# n = n * i
# return n
# L = [1,2,3,4]
# print(prod(*L))
def prod(num):
return reduce(lambda x, y: x*y, num)
L = [1,2,3,4]
print(prod(L))
24
利用map和reduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456:
from functools import reduce
def str2float(s):
# 获取小数点的索引位置
period_index = s.index(".")
# 获取小数点左侧的字符
left_char = s[:period_index]
# 获取小数点右侧的字符
right_char = s[period_index + 1:]
# 定义字符串转数字的函数convert()
def convert(i):
digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
return digits[i]
# 转换小数点左侧数字
left_sum = reduce(lambda x,y: x * 10 + y, map(convert, left_char))
# 转换小数点右侧数字
mid_num = reduce(lambda x,y: x * 10 + y, map(convert, right_char))
right_sum = mid_num / 10 ** len(right_char)
return left_sum + right_sum
print(str2float('123.456'))
python123.456
四、filter函数
类似map(),filter()
接收一个函数和序列,将传入的函数依次作用于每个元素,然后根据返回时True还是False决定保留还是丢弃该元素。
例如在一个list中,删掉偶数,只保留奇数,可以这么写:
def is_odd(n):
return n % 2 == 1
list(filter(is_odd, [1,2,4,5,6,9,10,15]))
[1, 5, 9, 15]
把一个序列中的空字符串删掉,可以这么写:
def not_empty(s):
return s and s.strip()
list(filter(not_empty,['A','','B', None, 'C',' ']))
['A', 'B', 'C']
filter()函数返回的是一个Iterator,是一个惰性序列,因此要强迫filter()完成计算结果,就需要用list()函数获得所有的结果并返回list.
# 筛选素数
# 构造一个从3开始的奇数序列
def _odd_iter():
n = 1
while True:
n = n + 2
yield n
#定义一个筛选函数
def _not_divisible(n):
return lambda x: x % n > 0
# 定义一个生成器,不断返回下一个素数:
def primes():
yield 2
it = _odd_iter() # 初始序列
while True:
n = next(it) # 返回序列的第一个数
yield n
it = filter(_not_divisible(n), it) # 构造新序列
# primes()是一个无限序列,所以调用的时候需要设置一个退出循环条件:
# 打印100以内的素数
for n in primes():
if n < 100:
print(n)
else:
break
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97
三、Sorted函数
soted()函数是Python内置函数,可以对list进行排序。
sorted([36,5,-12,9,21])
[-12, 5, 9, 21, 36]
key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序。对比原始的list和key = abs
处理过
list = [36, 5, -12, 9, -21]
key = [36, 5, 12, 9, 21]
默认情况下,对字符串排序,是按照ASCII的大小比较的,由于'Z' < 'a'
,结果,大写字母Z会排在小写字母a的前面。
sorted(['bob', 'about', 'Zoo', 'Credit'])
['Credit', 'Zoo', 'about', 'bob']
忽略大小写,按照字母序排序。用一个key函数把字符串映射为忽略大小写排序即可。忽略大小写来比较两个字符串,实际上就是先把字符串都变成大写(或者都变成小写),再比较。
sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
['about', 'bob', 'Credit', 'Zoo']
反向排序,不必改动key函数,可以传入第三个参数reverse=True
sorted(['bob','about','Zoo','Credit'], key = str.lower, reverse = True)
['Zoo', 'Credit', 'bob', 'about']
小结:sorted()函数排序的关键在于实现一个映射函数。
# 请用sorted()对上述列表分别按名字排序
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
sorted_list = sorted(L, key = lambda x: x[0])
print(sorted_list)
[('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)]
# 请用sorted()对上述列表分别按成绩排序
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
sorted_list = sorted(L, key = lambda x: x[1])
print(sorted_list)
[('Bart', 66), ('Bob', 75), ('Lisa', 88), ('Adam', 92)]
评论 (0)