注:该学习笔记是根据曾志贤老师编写的《从Excel到Python,用Python轻松处理Excel数据》所学习整理的笔记。
第十章
这里写目录标题
第十章 常用高阶函数应用
高阶函数时Python中非常有用的功能函数。一个函数可以接收另一个函数作为参数,这样的函数叫作高阶函数。Python中内置的高阶函数有map函数、filter函数和sorted函数。
一、map转换函数
map函数可以根据提供的函数对指定序列做映射。
map函数接收两个参数,第1个参数为函数,第2个参数为序列。
map函数的功能是将传入的函数依次作用于传入序列的每个元素,返回的结果是一个可迭代对象。
- 函数语法结构:
- map(func, *iterables)
- 参数说明:
- func:函数
- iterables:一个或多个序列
1、map函数的第1个参数为内置函数
# 常规写法
print([len(n) for n in ['8', '99', '666']])
# map写法
print(list(map(len, ['8', '99', '666'])))
2、map函数的第1个参数为自定义函数
# 自定义函数
def square(x):
return x**2
# 常规写法
print([square(n) for n in [1, 2, 3, 4]])
# map写法
print(list(map(square, [1, 2, 3, 4])))
3、map函数的第1个参数为匿名函数
# 常规写法
print([(lambda x: x**2)(n) for n in [1, 2, 3, 4]])
# map写法
print(list(map(lambda x: x**2, [1, 2, 3, 4])))
4、map函数的第1个参数时多参数
# 常规写法
print([a + b for a, b in zip([1, 2], [10, 20])])
# map写法
print(list(map(lambda x, y: x+y, [1, 2], [10, 20])))
案例一:转换二维表为一维表
将“分数表”中的各科分数转换成一维表。
import xlrd
from xlutils.copy import copy
wb = xlrd.open_workbook('10-2.xls')
ws1 = wb.sheet_by_name('分数表')
ws2 = wb.sheet_by_name('转换表')
nwb = copy(wb)
nws = nwb.get_sheet('转换表')
nws.write(0, 0, '合并转换')
row_num = 0
lst = []
for i, j, k, l in ws1.get_rows():
lst.append([[i.value]*3, ['语文', '数学', '英语'], [j.value, k.value, l.value]])
for i, j, k in lst[1:]:
for row_val in map(lambda a, b, c: '{}({}{})'.format(a, b, c), i, j, k):
row_num += 1
nws.write(row_num, 0, row_val)
nwb.save('10-2-1.xls')
二、filter筛选函数
filter函数用于筛选序列,去除不符合条件的元素,返回符合条件的元素并组成新的序列。
filter函数接收两个参数,第1个参数是函数,第2个参数为序列。
序列的每个元素作为参数传递给函数进行判断,返回True或False,将返回True对应的元素放到新的序列。
- 函数语法结构:
- filter(function, iterable)
- 参数说明:
- function:判断函数,能返回逻辑值True或False的函数。
- iterable:可迭代对象。
1、使用filter筛选函数筛选列表
lst = [3, 56, 87, 66, 77, 88, 99]
# 常规写法
print([n for n in lst if n >= 80])
# filter使用自定义函数写法
def fun(x):
return x >= 80
print(list(filter(fun, lst)))
# filter使用匿名函数写法
print(list(filter(lambda x: x >= 80, lst)))
案例一:计算美式排名、中式排名
对总分分别进行美式、中式排名。
import xlrd
from xlutils.copy import copy
wb = xlrd.open_workbook('10-4.xls')
ws = wb.sheet_by_name('分数表')
nwb = copy(wb)
nws = nwb.get_sheet('分数表')
lst = ws.col_values(1)[1:]
for row_num in range(1, ws.nrows):
# 美式排名
en = 1 + len(list(filter(lambda x: lst[row_num - 1] < x, lst)))
# 中式排名
cn = 1 + len(list(filter(lambda x: lst[row_num - 1] < x, set(lst))))
nws.write(row_num, 2, en)
nws.write(row_num, 3, cn)
nwb.save('10-4-1.xls')
三、排序函数sort与sorted
sort函数:在原列表中排序
sorted函数:排序后会生成一个新的列表
1、排序函数sort
sort函数应用于对列表排序,排序之后列表中元素的顺序会改变。
sort只能对列表排序
- 语法结构:
- sort(key=None, reverse=False)
- 参数说明:
- key:可选参数,用户可以用函数来确定比较方式。
- reverse:可选参数,当reverse=False时,按升序排序;当reverse=True时,按降序排序。默认为False。
注意:sort函数的key参数和reverse参数是命名关键字参数,在给两个参数传入值时,必须要用“参数=值”的格式书写。
# 降序
l1 = [8, 15, 19, 10]
l1.sort(reverse=True)
print(l1)
# 升序
l2 = [8, 15, 19, 10]
l2.sort(reverse=False)
print(l2)
# 匿名函数排序
l3 = [('张三', 88), ('李四', 99), ('王五', 85)]
l3.sort(key=lambda x: x[1], reverse=True)
print(l3)
2、排序函数sorted
sorted函数不会改变原来的序列对象,而是返回一个新的列表。
sorted函数可以对仍和一个可迭代对象排序,执行后返回新列表。
- 语法结构:
- sorted(iterable, key=None, reverse=False)
- 参数说明:
- iterable:必选参数,仍和可迭代的对象。
- key:可选参数,用户用函数来确定比较方式。
- reverse:可选参数,
注意:sorted函数的iterable参数不是命名关键字参数,而key参数和reverse参数是命名关键字参数。
# 默认升序
print(sorted([4, 2, 6]))
# 字符串默认升序是依据长度来升序的,可以不写key=len
print(sorted(['cb', 'a', 'cba'], key=len))
# 使用匿名函数排序
print(sorted({'b-10', 'c-8', 'a-14'}, key=lambda x: int(x.split('-')[1])))
案例一:对字符串中的数据排序
将销量列表中的销量进行降序排序。
import xlrd
from xlutils.copy import copy
wb = xlrd.open_workbook('10-6.xls')
ws = wb.sheet_by_name('销量表')
nwb = copy(wb)
nws = nwb.get_sheet('销量表')
for row_num in range(1, ws.nrows):
# 将B列数据按照“、”进行拆分,并放入列表
lst = ws.cell_value(row_num, 1).split('、')
# 将列表进行排序,采用自定义函数提取数字,进行降序
lst.sort(key=lambda x: int(x.split(':')[1]), reverse=True)
# 将拆分的列表按照“、”重新组合
val = '、'.join(lst)
nws.write(row_num, ws.ncols - 1, val)
nwb.save('10-6-1.xls')
案例二:改进美式排名和中式排名的算法
使用sorted函数进行排名
import xlrd
from xlutils.copy import copy
wb = xlrd.open_workbook('10-7.xls')
ws = wb.sheet_by_name('分数表')
nwb = copy(wb)
nws = nwb.get_sheet('分数表')
# lst1用于美式排名,对列表进行重新排序。
lst1 = sorted(ws.col_values(1)[1:], reverse=True)
# lst2用于中式排名,首先将指定列的数据放入集合去重复,在进行重新排序。
lst2 = sorted(set(ws.col_values(1)[1:]), reverse=True)
for row_num in range(1, ws.nrows):
# 美式排名,在列表中查找指定列的位置,返回所在位置数,因为从0开始,所有结尾+1
en = lst1.index(ws.cell_value(row_num, 1)) + 1
# 中式排名,在列表中查找指定列的位置,返回所在位置数,因为从0开始,所有结尾+1
cn = lst2.index(ws.cell_value(row_num, 1)) + 1
nws.write(row_num, 2, en)
nws.write(row_num, 3, cn)
nwb.save('10-7-1.xls')