Python入门:对Excel数据处理的学习笔记【第九章】自定义函数

注:该学习笔记是根据曾志贤老师编写的《从Excel到Python,用Python轻松处理Excel数据》所学习整理的笔记。

第九章 自定义函数

一、自定义函数编写规范

1、函数的定义

  • 语法结构:
    • def 函数名(参数):
      • 函数体
      • return 返回值
    • 说明:
      • def:函数的关键字,不能没有,也不能改,此关键字表示自定义函数。
      • 函数名:函数的名称,根据函数名调用函数。不能一数字开头,尽量定义成可以表示函数功能的名称。
      • 参数:为函数体提供数据。参数是被放在小括号中的,可以设置多个参数,参数之间用逗号分隔。在小括号后的后面加冒号。
      • return 返回值:整体作为自定义函数的可选参数,用于设置自定义函数的返回值,也就是说自定义函数可能有返回值,也可能没有返回值,视情况而定。
        注意:函数体和返回值语句要做缩进处理,也就是从冒号开始换行的语句都要做缩进处理。

2、自定义函数的创建与调用

  • 在自定义函数时,函数中的参数被称为形参,也就是形式上的参数,用于接收传递过来的数据。
  • 在调用自定义参数时,向函数的参数写入的值被叫做实参,也就是实际上的参数。
# 有返回值的自定义函数  
def total_sum1(price, amount):  
    money = price * amount  
    return money  
# 返回200  
print(total_sum1(10, 20))  
  
# 无返回值的自定义函数  
def total_sum2(price, amount):  
    str = '单价:{} 数量:{} 金额:{}'.format(price, amount, price * amount)  
    print(str)  
# 返回单价:10 数量:20 金额:200  
total_sum2(10, 20)
案例一、平均函数的定义及应用
  • 将每个人1~12月的工资进行平均,然后写入N列对应的单元格。

在这里插入图片描述

# 自定义平均函数  
def average(lst):  
    num = sum(lst) / len(lst)  
    avg = float('{:.2f}'.format(num))  
    return avg  
  
# 数据处理  
import xlrd  
from xlutils.copy import copy  
wb = xlrd.open_workbook('9-2.xls')  
ws = wb.sheet_by_name('工资表')  
nwb = copy(wb)  
nws = nwb.get_sheet('工资表')  
for row_num in range(1, ws.nrows):  
    nws.write(row_num, ws.ncols - 1, average(ws.row_values(row_num)[1:-1]))  
nwb.save('9-2-1.xls')

二、必选参数的写法及应用

1、必选参数(位置参数)

必选参数就是函数调用时必须要传入值的参数,既不能多,也不能少。必选参数也可以叫作位置参数。

# 自定义函数  
def level(number, lv1, lv2, lv3):  
    # number、lv1、lv2、lv3 必选参数  
    if number >= 90:  
        return lv1 #  
    elif number >= 60:  
        return lv2  
    elif number >= 0:  
        return lv3  
  
# 调用1  
for score in [95, 63, 58, 69, 41, 88, 96]:  
    print(score, level(score,  '优', '良', '差'))
案例一、给号码分段

给工作表B列按照每4位分一段,如果不够4位,也要分成一段。

在这里插入图片描述

# 自定义函数  
def intercept(s, num, delimiter):  
    # s:将数据转换为字符串,num:将要分几段,delimiter:分割使用的符号  
    s1 = str(s)  
    lst = []  
    # 循环字符串长度,步长为num  
    for n in range(0, len(s1), num):  
        # 截取字符串num的长度,放入列表  
        lst.append(s1[n:n + num])  
    # 将分割符号与列表进行重新组合  
    s2 = delimiter.join(lst)  
    # 将结果返回给函数  
    return s2  
  
# 使用自定义函数  
import xlrd  
from xlutils.copy import copy  
wb = xlrd.open_workbook('9-4.xls')  
ws = wb.sheet_by_name('卡号表')  
nwb = copy(wb)  
nws = nwb.get_sheet('卡号表')  
for row_num in range(1, ws.nrows):  
    val = ws.cell_value(row_num, 1)  
    nws.write(row_num, ws.ncols - 1, intercept(val, 4, '-'))  
nwb.save('9-4-1.xls')

三、可选参数的写法及应用

1、可选参数(默认参数)

  • 可选参数表示在调用函数时可传可不传该参数的值。
  • 在定义可选参数时,要设置一个值,这个值叫作默认值,所以可选参数也叫作默认参数。
  • 在调用函数时,如果可选参数没有传入值,则使用可选参数的默认值。
  • 在自定义函数时,既有必选参数,又有可选参数,要先定义必选参数,在定义可选参数。在调用函数时也一样,要先传必选参数,在传可选参数。
# 自定义函数  
def mid(iterable, start=0, lenght=1):  
    # 设置可选参数默认值的方式是:参数=值,不传入参数时,使用默认值  
    return iterable[start:start+lenght]  
  
print(mid('abcdefgh'))  
print(mid('abcdefgh', 2))  
print(mid('abcdefgh', 2, 5))
案例一、模拟Vlookup函数的应用

按照“销售表”中A列的产品名,到“单价表”中查询对应的产品价格,将合计的价格写入“销售表”中。

在这里插入图片描述

# 自定义函数  
def vlookup(val, lst, num=1):  
    # 产品名、所在的列表、返回第几列  
    # 在lst第0列,查找产品名,返回它所在的位置  
    r = lst[0].index(val)  
    # 返回lst第num列,的第对应位置的值  
    v = lst[num][r]  
    return v  
  
# 引用自定义函数  
import xlrd  
from xlutils.copy import copy  
wb = xlrd.open_workbook('9-6.xls')  
ws1 = wb.sheet_by_name('单价表')  
ws2 = wb.sheet_by_name('销售表')  
nwb = copy(wb)  
nws = nwb.get_sheet('销售表')  
# 将单价表放入列表  
lst = [ws1.col_values(0)[1:], ws1.col_values(1)[1:]]  
for row_num in range(1, ws2.nrows):  
    # 提取行的所有值  
    vals = ws2.row_values(row_num)[:-1]  
    # 进行自定义函数的查询,并且计算  
    val = vlookup(vals[0], lst) * vals[1]  
    nws.write(row_num, ws2.ncols - 1, val)  
nwb.save('9-6-1.xls')

四、关键字参数的写法及应用

在函数调用时,通过“参数=值”的形式传入实参的方式叫作关键字参数,可以让函数更加清晰、易于使用,同时参数的书写可以不按顺序。

1、关键字参数

  • 关键字参数分为:
    • 普通关键字参数:可以用“参数=值”的方式传入实参也可以按参数位置的顺序直接传入实参。
    • 命名关键字参数:必须用“参数=值”的方式传入实参。
# 普通关键字参数  
def counter1(iterable, min, max):  
    lst = [v for v in iterable if v>=min and v<=max]  
    return lst  
  
# 按位置传递实参,必须按照顺序  
print(counter1([2, 3, 8, 3, 4, 5, 9], 3, 8))  
# 按关键字参数传递实参,可以不按照顺序  
print(counter1(max=8, min=3, iterable=[2, 3, 8, 3, 4, 5, 9]))  
  
  
# 命名关键字参数,*号以后得关键字,必须写为“参数=值”的格式  
def counter2(iterable, *, min, max):  
    lst = [v for v in iterable if v>=min and v<=max]  
    return lst  
# 按位置传递实参,必须按照顺序,且必须写命名参数  
print(counter2([2, 3, 8, 3, 4, 5, 9], min=3, max=8))  
# 如果不按照顺序传递参数,则都必须要命名参数  
print(counter2(max=8, min=3, iterable=[2, 3, 8, 3, 4, 5, 9]))
案例一、分类合并字符串

以“工资表”工作表的“部门”列为基准,合并“姓名”列。

在这里插入图片描述

# 自定义函数  
def combine(range, join_range, delimiter):  
    # 参数:作为key的列号、作为值的列号、连接符号  
    dic = {}  
    lst = []  
    # 将选择的两列使用zip重新组合,并放入循环  
    for x, y in zip(range, join_range):  
        # 判断字典是否存在key,并且放入对应的值  
        if not x in dic:  
            dic[x] = {y}  
        else:  
            dic[x].update({y})  
    # 循环字典,重新组合值,并且放入列表  
    for key, val in dic.items():  
        row_val = [key, delimiter.join(val)]  
        lst.append(row_val)  
    return lst  
  
# 引用自定义函数  
import xlrd  
from xlutils.copy import copy  
wb = xlrd.open_workbook('9-8.xls')  
ws1 = wb.sheet_by_name('工资表')  
ws2 = wb.sheet_by_name('结果表')  
nwb = copy(wb)  
nws = nwb.get_sheet('结果表')  
row_num = 0  
# 循环自定义列表,将值写入对应单元格  
for x, y in combine(ws1.col_values(0), ws1.col_values(2), '、'):  
    nws.write(row_num, 0, x)  
    nws.write(row_num, 1, y)  
    row_num += 1  
nwb.save('9-8-1.xls')

五、不定长参数的写法及应用

不定长参数是指定义的函数参数个数不确定,可以将不定长参数收纳在指定的容器中。

  • 不定长参数分为一下两种,*args和**kwargs
    • args与kwargs变量名称不是固定的,只是约定俗成的一种命名方式,用户可以修改成其他名称。不定长参数必须放在必选参数之后。
    • *args和**kwargs接收的数据类型不限,完全根据需求而定。

1、不定长参数 *args

*args:以一个星号开头,然后接args变量,这种参数接收的值存储在元组中,即args是一个元组类型。

# *args 以元组的形式储存不确定的个数的参数  
def subtotal(iterable, *args):  
    lst = []  
    for fun in args:  
        lst.append(fun(iterable))  
    return lst  
# 第一组为必选参数,后面为添加的不定长参数
print(subtotal([7,8,9,10],max,min,sum))  
# 返回 最大值:10、 最小值:7、和:34

2、不定长参数 **kwargs

**kwargs:以两个星号开头,然后接kwargs变量,这种参数接收的值存储在字典中,即kwargs是一个字典类型。

# **kwargs 以字段的形式储存不确定的个数的参数  
def subtotals(iterable, **kwargs):  
    lst = []  
    for key, val in kwargs.items():  
        lst.append([key, val(iterable)])  
    return lst  
# 第一组为必选参数,后面为添加的不定长参数,由于是字典形式,后面的参数相当于字典的key=val  
print(subtotals([7, 8, 9,10], 求和=sum, 最大=max, 最小=min, 计数=len))  
# 返回 [['求和', 34], ['最大', 10], ['最小', 7], ['计数', 4]]
案例一、替换函数增强版

将“书单表”工作表汇总的B列书名使用书名号进行分割。

在这里插入图片描述

# 自定义函数  
def replaces(string, new, *old):  
    for o in old:  
        # 使用字符串替换函数进行替换,并且赋值给自己  
        string = string.replace(o, new)  
    return string  
  
# 引用自定义函数  
import xlrd  
from xlutils.copy import copy  
wb = xlrd.open_workbook('9-10.xls')  
ws = wb.sheet_by_name('书单表')  
nwb = copy(wb)  
nws = nwb.get_sheet('书单表')  
for row_num in range(1,ws.nrows):  
    # 这里需要提取成字符串,而不是列表,所以至取第1列  
    vals = ws.row_values(row_num)[1]  
    nws.write(row_num, ws.ncols - 1, '《' + replaces(vals, '》《', ' ', '|') + '》')  
nwb.save('9-10-1.xls')

六、匿名函数的写法及应用

  • 匿名函数指无需定义标识符的函数或者子程序。
  • python中用lambda关键字定义匿名函数,只用表达式而无需声明。
  • 使用匿名函数的好处:匿名函数没有名字,不必担心函数名冲突。
  • 匿名函数也是一个函数对象,可以把匿名函数赋值给一个变量,这样变量名就相当于函数名,可以利用变量来调用该函数。

1、匿名函数的语法结构

  • lambda与def的区别:
    • lambda是表达式,只能封装有限的业务逻辑,适用于编写简单的函数。
    • def是语句块,适用于处理更大量的业务。

lambda语法结构:

fun = lambda[参数]:expression
#变量 = lambda[参数]:处理表达式及返回值

2、匿名函数的常见书写方式

# 将匿名参数赋值给变量  
fun1 = lambda x: x*10  
print(fun1(20))  
  
# 必选参数  
fun2 = lambda x, y: x+y  
print(fun2(10, 20))  
  
# 可选参数  
fun3 = lambda x, y=30: x+y  
print(fun3(10))  
  
# 不定长参数*args  
fun4 = lambda x, *args: [f(x) for f in args]  
print(fun4([3, 4, 5, 6], sum, max, min, len))  
  
# 不定长参数**kwargs  
fun5 = lambda x, **kwargs: [key + ':' + str(val(x)) for key, val in kwargs.items()]  
print(fun5([3, 4, 5, 6], 求和=sum, 最大=max, 最小=min, 数量=len))

案例一、根据身份证号判断性别

将“身份证表”中的A列身份证号的第17位数字判断性别,奇数为男性,偶数为女性。然后写入B列。

在这里插入图片描述

import xlrd  
from xlutils.copy import copy  
wb = xlrd.open_workbook('9-12.xls')  
ws = wb.sheet_by_name('身份证表')  
nwb = copy(wb)  
nws = nwb.get_sheet('身份证表')  
for row_num in range(1, ws.nrows):  
    # 列表推导式,整型身份证号的倒数第二位,整除2的余数判断男女  
    card = lambda id: '男' if int(id[-2]) % 2 == 1 else '女'  
    val = ws.cell_value(row_num, 0)  
    nws.write(row_num, ws.ncols - 1, card(val))  
nwb.save('9-12-1.xls')

七、自定义函数存放在.py文件中

自定义函数可以被单独存放在一个.py文件中,这样其他.py文件也可以调用,实现自定义函数的复用。

1、函数定义在单独.py文件中

# 引用指定模块(会引用所有函数)
import 模块

# 引用指定模块所有的函数
from 模块 import *

# 引用指定模块下的指定单个或多个函数
from 模块 import 函数1,函数2

2、函数定义在文件夹中

如果模块较多的话,可以将多个模块放入包中(文件夹)

# 引用包中的所有模块
from 包名称 import *

# 引用包中的指定模块的指定函数
from 包名称.模块 import 函数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MeJonKing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值