Day04,python概念:函数基本知识(定义,参数,lambda,map,filter表达式,应用于工具)

声明
1)该文章整理自网上的大牛无私奉献的资料,具体引用的资料请看参考文献。
2)本文仅供本人学习记录,非商用。所以每一部分具体的参考资料并没有详细对应。如果某部分不小心侵犯了大家的利益,还望海涵,并联系博主删除。
3)博主才疏学浅,文中如有不当之处,请各位指出,共同进步,谢谢。
本节学习了Python中的函数,和其他编程语言一样,函数可以最大化代码的重用率,最小化代码的冗余,同时使用函数将过程分解使得程序更具有逻辑性。

1.函数的使用

函数的定义:def 方法名(参数1,参数2,):函数体

def add(x):
    return x + 10

函数的调用:函数名(实际参数)

add(1)  # -->11

在这里插入图片描述

2.函数变量的作用域

全局变量global与局部变量local

x = 100
def my_function():
    x = 50
    return x
 
print(x)
my_function()
print(x)    # 打印结果 100 100

这是由于函数内部定义的x是局部变量,外部的x是全局变量。若想在函数内部修改全局变量需要添加global

x = 100
def my_function():
    global x
    x = 50
 
print(x)
my_function()
print(x)     # 打印结果 100 50

使用global声明后函数内部修改了全局变量x。

列表的全局变量与局部变量

l =['aaaa','bbb','ccc']
 
def my_function():
    l[0] = '0'
 
print(l)
my_function()
print(l)
 
# 打印结果 ['aaaa', 'bbb', 'ccc'] ['0', 'bbb', 'ccc']

为什么列表不用声明局部变量就会被修改呢?

答:因为列表是可变类型,传递地址引用,函数内操作可能会影响原始值。如果不希望影响原始值可以将原始值复制一份将副本传入,如l.copy()。而像数值或者字符串元组这些不可变类型的数据,会不可变类型,传递副本给函数,函数内操作不影响原始值。

内置bulid-in

l = [13,2,1]
def sorted():
    return 1
 
sorted(l)  # 会报错

内置函数和变量会拥有最高的作用域,切忌使用python内置的对象作为函数名或变量名,会造成不必要的麻烦。
封装作用域enclousure

def my_function():
    x = 33
    def inner():
        x = 20  # 封装的
    inner()
    print(x)
 
my_function()
 
# 打印结果 33

函数内部再嵌套函数称为封装的作用域。

想要在封装的作用域内使用外侧函数的变量需要使用nonlocal声明。如下图所示

def my_function():
    x = 33
    def inner():
        nonlocal x
        x = 20
    inner()
    print(x)
 
my_function()
 
# 打印结果 20

总结:
作用域分为 内置>全局>局部>封装的
内部想使用外部:gloabl声明
封装想使用内部:nonlocal声明

3.参数

参数匹配的原则

位置匹配
def func(a,b,c):
    print(a,b,c)
 
func(1,2,3)   #func已经有自带的print,所以不需要在打印print
 
# 打印结果 1 2 3

关键字匹配

def func(a,b,c):
    print(a,b,c)
 
func(c=5,b=2,a=4)
 
# 打印结果 4 2 5

默认值:调用时可省略传值

def func(a,b=3,c=4):
    print(a,b,c)
 
func(1)
 
# 打印结果 1 3 4
def func(a,b=3,c=4):
    print(a,b,c)
 
func(1, c=5)
 
# 打印结果 1 3 5

args:传递任意数量的参数
有需求为打印某名学生考试成绩的平均值,假设他有两门考试,定义avg函数,计算他成绩的平均值

def avg(score1,score2):
    return (score1 + score2) / 2
 
avg(98.0,96.0)
 
# 打印结果 97.0

假设他增加了一门考试,avg函数应改为传三个参数的,如果另一名学生有四门考试的话,还需要重新写一个平均值函数。

def avg(score1,score2,score3):
    return (score1 + score2 + score3) / 3
 
avg(98.0,96.0,97.0)
 
# 打印结果 97.0

为了解决这样的问题,引入可接受任意数量的*args

def avg(score1,*args):
    return (score1+sum(args)) / (len(args)+1)
 
result = avg(98.0,96.0,98.0,100.0)
print(result)
# 打印结果 98.0
 
 
score = (98.0,96.0,98.0,100.0)
print(avg(score))  # 直接传入元组会报错,需要将元组用*解包
print(avg(*score))  # 打印结果:98.0

**kwargs:传递任意指定值的参数

有需求打印员工的信息,造打印函数display_employee()打印员工的姓名,年龄,工作,可以写成如下信息

def display_employee(name,age,job):
    print('name:{},age:{},job:{}'.format(name,age,job))
 
display('Jerry',20,'dev')

这样写需要调用时一一对应,很容易写错,并且不好扩展。

def display(**kwargs):
    for k,v in kwargs.items():
        print("{}:{}".format(k,v))
 
display(name = 'tom', age = 20, job='dev', department = 'develop')
 
 
# 打印结果 
# name:tom
# age:20
# job:dev
# department:develop
 
d = {'name':'lili','age':20, 'job':'dev'}
display(d)  # 报错,不能直接传入字典,需要将字典用**解包
display(**d)  #打印结果

lambda表达式

定义

可能只使用一次的函数为了简洁可以使用lambda匿名函数

基本格式

lambda 参数1,参数2,…:函数

可以将lambda表达式用一个变量存储起来

f = lambda name:print(name)
f('Tom')  # 打印结果 Tom
 
f2 = lambda x,y:print(x+y)
f2(3,4)  # 打印结果 7

有需求对用户使用不同语言say hello 可以写成如下代码

def hello_chinese(name):
    print('你好:', name)
 
def hello_englise(name):
    print('hello:',name)
 
 
while True:
    name = input('请输入您的姓名:\n')
    if name == 'stop':
        break
    language = input('请选择语言:\n c-->中文版\n e-->英文版\n')
    if language == 'c':
        hello_chinese(name)
    elif language == 'e':
        hello_english(name)

如果此时需要加入日文版,再写一个hello_japanese函数可能比较繁琐,使用lambda表达式

def hello_chinese(name):
    print('你好:', name)
 
def hello_english(name):
    print('hello:',name)
 
 
while True:
    name = input('请输入您的姓名:\n')
    if name == 'stop':
        break
    language = input('请选择语言:\n c-->中文版\n e-->英文版\n j-->日文版 \n')
    if language == 'c':
        hello_chinese(name)
    elif language == 'e':
        hello_english(name)
    elif language == 'j':
        (lambda name : print('莫西莫西', name))(name)

升级版,不使用if…elif…elif 使用字典表模拟其他函数中的switch,使用了委托的思想

def hello_chinese(name):
    print('你好:', name)
 
def hello_english(name):
    print('hello:',name)
 
operation = {
    'c':hello_chinese,
    'e':hello_english,
    'j':lambda name : print('莫西莫西', name)
}
while True:
    name = input('请输入您的姓名:\n')
    if name == 'stop':
        break
    language = input('请选择语言:\n c-->中文版\n e-->英文版\n j-->日文版 \n')
    operation.get(language,lambda name:print("此版本不存在"))(name)

升级版 使用函数调用函数,使用委托的思想

def hello_chinese(name):
    print('你好:', name)
 
def hello_english(name):
    print('hello:',name)
 
def hello(action,name):
    action(name)
 
operation = {
    'c':hello_chinese,
    'e':hello_english,
    'j':lambda name : print('莫西莫西', name)
}
 
while True:
    name = input('请输入您的姓名:\n')
    if name == 'stop':
        break
    language = input('请选择语言:\n c-->中文版\n e-->英文版\n j-->日文版 \n')
    hello(operation.get(language,lambda name:print("此版本不存在")),name)

map函数

功能:将一个可迭代对象都传入一个函数中进行处理

格式:map(函数,可迭代对象),map中函数可以事先定义好也可以使用lambda表达式

需求:将元素为1-20的列表中的每个数值加5存成一个新的列表

有三种方法

l = list(range(1,21))
result = []
 
# 1.使用for循环
for x in l:
    result.append(x+5)
 
# 2.使用推导
result = [x+5 for x in l]
 
# 3.使用map函数
def add_num(x):
    return x+5
 
result = list(map(add_num,l))

filter函数

功能:将可迭代对象都通过一个函数进行过滤

格式:filter(函数,可迭代对象) filter中函数可以事先定义好也可以使用lambda表达式

需求:将元素为1-20的列表中的偶数存成一个新的列表

有三种方法

l = list(range(1,21))
result = []
 
# 1.使用for循环
for x in l:
    if x % 2 == 0:
        result.append(x)
 
# 2.使用推导
result = [x for x in l if x % 2 == 0]
 
# 3.使用map函数
def even_num(x):
    return x % 2 == 0
 
result = list(filter(even_num,l))

这三种方法:因推导底层使用c语言速度最快,更推荐使用推导方法。但需要更复杂的操作与过滤就需要使用map和filter。

总结

在这里插入图片描述

练习

在这里插入图片描述
在这里插入图片描述
3、在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值