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)

# 打印结果 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。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值