Python基础知识学习(五)——函数:函数的使用、作用域、lambda表达式与map、filter函数

685-杜同学

发表文章数:68

热门标签

首页 » Python » 正文

本节学习了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。

标签:

拜师教育学员文章:作者:685-杜同学, 转载或复制请以 超链接形式 并注明出处 拜师资源博客
原文地址:《Python基础知识学习(五)——函数:函数的使用、作用域、lambda表达式与map、filter函数》 发布于2019-12-27

分享到:
赞(0) 打赏

评论 抢沙发

评论前必须登录!

  注册



长按图片转发给朋友

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

Vieu3.3主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录