Python零基础速成班-第5讲-Python函数,Function和Lambda基础

Python零基础速成班-第5讲-Python函数,Function和Lambda基础

学习目标

  1. Function函数
  2. Lambda Function函数
  3. 课后作业(4必做)

友情提示:将下文中代码拷贝到JupyterNotebook中直接执行即可,部分代码需要连续执行。

1、Function 函数

函数的定义:

  1. 函数是组织好的,可重复使用的,用来实现单一或相关联功能的代码块。
  2. 函数能提高应用的模块性,和代码的重复利用率。
  3. 函数可以接受任意数量和类型的输入参数,并返回任意数量和类型的输出结果。

1.1Python中函数的规则:

  1. 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
  2. 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
  3. 函数内容以冒号起始,并且缩进。
  4. return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
  5. 函数必须经过调用才能运行。

不做任何事情的空函数,pass表示函数不做任何操作

def do_nothing():
    pass
type(do_nothing)
function

函数只有在调用的时候才会执行

def output():
    print("hello world!")
    
output()
hello world!

一个没有参数和返回值的函数

def greeting():
    print("这是一个没有参数和返回值的函数!")


a = greeting()
这是一个没有参数和返回值的函数!

没有参数且返回布尔值的函数

def im_handsom():
    return True
    
if im_handsom():
    print("yes,you are so handsom")
else:
    print("hehe")
yes,you are so handsom

带有参数但不返回任何内容的函数

def greeting(name):
    print("hello %s"% name)
    
#调用函数
greeting("Lily")
hello Lily

带有参数和返回值的函数

def greetingwithre(name):
    return "hello " + name
    

print(greetingwithre("Lily"))
hello Lily

1.2 函数的参数

  1. 参数分为形参(形式参数)和 实参(实际参数)。
  2. 形参又分为:位置参数、关键字参数、默认参数、可变参数。
  3. 形参是在定义函数的时候给出的。
  4. 实参是在调用函数的时候给出的。

1.2.1 Positional Arguments 位置参数

位置参数是指其值按顺序复制到相应的参数中。

def students_info(age1,age2,age3):
    return {"lily":age1,"adam":age2,"sam":age3}

students_info(18,20,25)
{'lily': 18, 'adam': 20, 'sam': 25}

1.2.2 Keyword Arguments 关键字参数

为了避免位置参数混淆,您可以通过相应参数的名称来指定参数,即使顺序与函数中的定义不同,也可以保证参数传入的正确性。

def students_info(age1,age2,age3):
    return {"lily":age1,"adam":age2,"sam":age3}

students_info(age3 = 30,age2 = 20, age1 = 18)
{'lily': 18, 'adam': 20, 'sam': 30}

1.2.3 Default Parameter Values 默认参数

如果调用者不设置参数的传入值,可以为参数设置默认值。
dessert = “pudding”,调用者不设置参数的传入值,则使用默认值。

def menu(wine,entree,dessert = "pudding"):
    return {"wine":wine,"entree":entree,"dessert":dessert }
menu("mojito","chicken")
{'wine': 'mojito', 'entree': 'chicken', 'dessert': 'pudding'}

如果调用者提供值,则默认值将被覆盖。
调用者设置参数的传入值"cake",则默认值"pudding"被覆盖。

def menu(wine,entree,dessert = "pudding"):
    return {"wine":wine,"entree":entree,"dessert":dessert }
menu("mojito","chicken","cake")
{'wine': 'mojito', 'entree': 'chicken', 'dessert': 'cake'}

1.2.4 Gather Positional Arguments with * ,带*号的位置参数

*args实现传入参数以元组(tuple)的形式提供给函数,格式为tuple,多值。

def print_arg(*args):
    print("positinal args:",args)

print_arg(1,2,3,4,4)
positinal args: (1, 2, 3, 4, 4)

函数会自动匹配传入参数,并将剩下的多值变为tuple

def print_requried_args(r1,r2,*a):
    print("r1:",r1)
    print("r2:",r2)
    print("args:",a)
    
print_requried_args(1,2,3,4,5,6,7)
r1: 1
r2: 2
args: (3, 4, 5, 6, 7)

1.2.5 Gather Positional Arguments with ** ,带**号的位置参数

**kwargs实现传入参数以字典(dict)的形式提供给函数,格式为dictionary,键值对多值。

def print_kwargs(**kwargs):
    print("keywords args:", kwargs)
    
print_kwargs(first = 1, second = 2)
keywords args: {'first': 1, 'second': 2}

函数会自动匹配传入参数,并将剩下的多值变为tuple和dict

def print_all_args(req1,*args,**kwargs):
    print("required arg1:",req1)
    print("positional args:",args)
    print("keyword args:",kwargs)
print_all_args(1,2,3,4,5,name = "Lily",gender = "female")
required arg1: 1
positional args: (2, 3, 4, 5)
keyword args: {'name': 'Lily', 'gender': 'female'}
def print_all_args(req1,option = "choose",*args,**kwargs):
    print("required arg1:",req1)
    print("option arg1:",option)
    print("positional args:",args)
    print("keyword args:",kwargs)
print_all_args(1,2,3,4,5,name = "linda")
required arg1: 1
option arg1: 2
positional args: (3, 4, 5)
keyword args: {'name': 'linda'}

1.3 函数嵌套

在一个函数中定义了另外一个函数,参数按照先后顺序传入
如下例:square = exp_factory(3)表明n=3,square(2)表明a=2,最后执行2**3

def exp_factory(n):
    def exp(a):
        return a**n
    return exp

square = exp_factory(3)
square(2)
8

exp_factory(2)(3)表明先传入参数2,即n=2,后传入3,即a=3,最后执行3**2

def exp_factory(n):
    def exp(a):
        return a**n
    return exp

exp_factory(2)(3)
9

1.4 函数作用域

1.局部变量
在函数内部定义的变量,只在函数内部起作用,函数执行结束后变量会自动删除。
2.全局变量
与局部变量对应,全局变量为能够作用于函数外的变量。

进阶提示:
全局变量主要有以下两种:
如果一个函数在函数体外定义,那么不仅仅在函数外可以访问到,在函数内部也可以访问到。
如果一个变量在函数体内部定义,并且是以global关键字修饰后,该变量也就成为全局变量函数体外也可以访问此变量。

局部变量,仅作用于函数内部

a=1
def fun():
    a=5
    print(a)
    
print(a)
fun()
1
5

加入globe关键字后变为全局变量

a=1
def fun1():
    global a
    a=5
    print(a)
    
fun1()
print(a)
5
5

1.5类型注解提示

name:str 传入参数类型
->str 返回值类型

def funtips(name : str) -> str:   
    return "Hello " + name
funtips("Tom")
'Hello Tom'

也可以直接说明传入参数类型和函数返回类型

def funtips1(num:"传入数字",n:"传入数字的几次方") -> "返回数字的n次方":   
    return num**n
funtips1(5,3)
125

2、Lambda函数

Lambda函数,即Lambda 表达式(lambda expression),是一个匿名函数(不存在函数名的函数),lambda和普通的Function函数相比,就是省去了函数名称而已。

我们可以把Lambda理解为小号精简版的Function函数,它有如下优点:

  1. 使用Python写一些执行脚本时,使用lambda可以省去定义函数的过程,让代码更加精简。
  2. 对于一些抽象的,不会别的地方再复用的函数,有时候给函数起个名字也是个难题,使用lambda不需要考虑命名的问题。
  3. 使用lambda在某些时候让代码更容易理解。
double = lambda a:a*2
double(2)
4

[2]为数组中第几个lambda函数 (2)为函数传入值x

many_function = [
    lambda x: x**2,
    lambda x: x**3,
    lambda x: x**4,
]
many_function[2](2)
16

[1]为字典中key值为1的lambda函数 (6)为函数传入值x

many_function_dict = { 
    1: lambda x: x**2,
    2: lambda x: x**3,
    3: lambda x: x**4
}
many_function_dict[1](6)
36

**x实现传入参数以字典(dict)的形式提供给函数,格式为dictionary,键值对多值。

double = lambda **x: print(x)
double(a=1,b=2,c="good")
{'a': 1, 'b': 2, 'c': 'good'}

*x实现传入参数以元组(tuple)的形式提供给函数,格式为tuple,多值。

double = lambda *x: print(x)
double("a","b","c",1,2)
('a', 'b', 'c', 1, 2)

2.1 filter()

filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新数组。

进阶提示:filter( )返回值为list数组,可以用list( )方法接收。

下例为从my_list数组中筛选偶数并返回成新数组

my_list = [1,2,3,4,5,6,7,8,9]
new_list = list(filter(lambda x:x%2 == 0, my_list))
new_list
[2, 4, 6, 8]

从1-11中筛选奇数并返回成新数组list3

list2 = [i for i in range(11)]
list3 = list((filter(lambda x:x%2 == 1,list2)))
list3
[1, 3, 5, 7, 9]

延申应用,从原数组中选取偶数并生成新数组,我们这里使用Numpy生成一个新数组[0,1,2,3…29]

import numpy as np
numlist = np.arange(30)
[i for i in numlist if i%2 == 0]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28]

以上语法等同于下例通过循环的方式来筛选偶数,明显比下例要简洁

new_list = []
for i in numlist:
    if i%2 == 0:
        new_list.append(i)
new_list
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28]

快速过滤以下数组中长度小于1的(在爬虫数据处理中很有用)

strlist=["!","我的","明","家乡在","人","。","今","北京"]
[word for word in strlist if len(word) > 1]
['我的', '家乡在', '北京']

2.2 map()

map()会根据提供的函数对指定序列做映射,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。
map(function_to_apply,list_of_inputs)

进阶提示:map( )返回值为list数组,可以用list( )方法接收。

items = [1,2,4,6,7]
squared = []
for i in items:
    squared.append(i**2)
squared
[1, 4, 16, 36, 49]

使用map函数快速实现将数组所有元素做2次方操作

items = [1,2,4,6,7]
squared = list(map(lambda x: x**2, items))
squared
[1, 4, 16, 36, 49]

进阶方法,也可以使用Numpy快速实现

import numpy as np
squared1 = np.array([1,2,4,6,7])**2
print(squared1)
[ 1  4 16 36 49]

设置体重、身高、年龄三个数组,分别带入函数basic_metabolic_rate_female中,计算女生基础代谢率,保留2位小数

def basic_metabolic_rate_female(weight,height,age):
    return ("%.2f" %(661+9.6*weight+1.72*height-4.7*age))
weightl = [67,57,67]
height1 = [1.67,1.67,1.67]
age1 = [31,31,21]

bmr = map(basic_metabolic_rate_female,weightl,height1,age1)
list(bmr)
['1161.37', '1065.37', '1208.37']

使用map加lambda语法,快速实现上述功能

weightl = [67,57,67]
he1 = [1.67,1.67,1.67]
age1 = [31,31,21]
basic_metabolic_rate = list(map(lambda w,h,a:"%.2f" %(661+9.6*w+1.72*h-4.7*a),weightl,he1,age1))
basic_metabolic_rate
['1161.37', '1065.37', '1208.37']

可以将函数写入数组中,用map函数实现多个函数同时执行效果

def multiply1(x):
    return x*x
def add1(x):
    return x+x

func1 = [multiply1,add1]

for i in range(5):
    print("i =",i)
    values = list( map(lambda x:x(i),func1) )
    print(values)
i = 0
[0, 0]
i = 1
[1, 2]
i = 2
[4, 4]
i = 3
[9, 6]
i = 4
[16, 8]

2.3Reduce

reduce() 函数会对参数序列中元素进行累积。
函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。
reduce(function, iterable[, initializer])

返回x+y,即依次将数组内的元素相加

from functools import reduce
reduce(lambda x,y: x+y, [1,11,22,33,44])
111
sum([1,11,22,33,44])
111

a,b: a if (a>b) else b,即依次循环求该数组最大值

max_num = lambda a,b: a if (a>b) else b
reduce(max_num,[1,4,6,-1,111,90])
111


3、课后作业,答案在下一讲

1、编写一个名为make_shirt() 的函数,传入参数为size+logo(默认值是"ilovechina"),这个函数应打印一个句子,说明T恤的尺码和字样。使用位置形参或关键字形参分别调用该函数。

您的代码:

2、已知一个数列:1、1、2、3、5、8、13、……,其规律为从第3项开始,每一项都等于其前两项的和,这个数列就是斐波那契数列。请求出符合斐波那契数列规律的第(27)项的值。

您的代码:

3、通过lambda和map方法设计一个男女宝宝身高预测计算器,公式为

女 : ( 男 + 女 ) 2 女:\frac{(男+女)}{2} 2(+)
男 : ( 男 + 女 ) 2 ∗ 1.08 男:\frac{(男+女)}{2}*1.08 2(+)1.08

并为以下组合计算宝宝预测身高(假设男宝宝1,女0):性别[1,0,1,0]父亲身高[175,180,172,178]母亲身高[160,165,159,162] 。

您的代码:

4、通过lambda和reduce的方法设计一个程序寻找随机数组(20个0~100)中的最小值。

您的代码:


4、上一讲Python零基础速成班-第4讲-Python基础(下),结构语句、循环 课后作业及答案

1、做一个简单的猜数字游戏(0-30内), 随机生成一个数字,给5次机会猜中,猜大猜小均有提示,5次机会后,游戏宣布结束。

import random
stery = random.randint(0,30)
times= 5
for i in range(1,times+1):
    userinput = int(input("Please enter a number between 0~30:\n>>>"))
    if userinput == stery:
        print("Great,you are right,the number is %s!" % stery)
        break 
    elif userinput > stery:
        print("Your input is too big!\nYour have %s times left,Good luck!" %(times-i))
    else:
        print("Your input is too small!\nYour have %s times left,Good luck!" %(times-i))
print("Game Over...")
Please enter a number between 0~30:
>>>15
Your input is too small!
Your have 4 times left,Good luck!
Please enter a number between 0~30:
>>>22
Great,you are right,the number is 22!
Game Over...

2、统计"I have a dream that one day this nation will rise up and live out the true meaning of its creed: We hold these truths to be self-evident, that all men are created equal." 每个英文字符出现的次数

str = "I have a dream that one day this nation will rise up and live out the true meaning of its creed: We hold these truths to be self-evident, that all men are created equal."
print({i:str.count(i) for i in set(str)})
{'m': 3, 'w': 1, 'c': 2, ':': 1, 'n': 8, 'b': 1, 'q': 1, '-': 1, 'e': 22, 'l': 8, 'd': 7, ',': 1, 'i': 8, ' ': 33, 'r': 7, 'W': 1, 'v': 3, '.': 1, 'p': 1, 'g': 1, 'y': 1, 'h': 8, 's': 6, 'f': 2, 'a': 13, 't': 16, 'I': 1, 'o': 6, 'u': 5}

3、打印9*9乘法表

for i in range(1,10):
    line=""
    for j in range(1,i+1):
        line+="{}*{}={}  ".format(j,i,j*i)
    print(line)
1*1=1  
1*2=2  2*2=4  
1*3=3  2*3=6  3*3=9  
1*4=4  2*4=8  3*4=12  4*4=16  
1*5=5  2*5=10  3*5=15  4*5=20  5*5=25  
1*6=6  2*6=12  3*6=18  4*6=24  5*6=30  6*6=36  
1*7=7  2*7=14  3*7=21  4*7=28  5*7=35  6*7=42  7*7=49  
1*8=8  2*8=16  3*8=24  4*8=32  5*8=40  6*8=48  7*8=56  8*8=64  
1*9=9  2*9=18  3*9=27  4*9=36  5*9=45  6*9=54  7*9=63  8*9=72  9*9=81  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值