全国青少年软件编程python四级(2021.9备考2)
python函数: 完成一定的功能,由若干语句组成的语句块。
函数的作用:
结构化变成对代码的最基本的封装,一般按照功能组织一段代码.
封装的目的为了复用,减少冗余代码.
代码更加简洁美观,可读易懂.
函数的分类:
内建函数: 如max(),reversed()等.
库函数: 如math.ceil()等.
标准函数、内建函数、第三方库函数
语法:
def 函数名(形参):
函数体(代码块)
[return 返回值]
函数名(实参)
函数名就是标识符,命名要求一样.
语句块必须缩进,约定4个空格.
python的函数没有return语句,隐式会返回一个None值.
定义中的参数列表成为形式参数,只是一种符号表达,简称形参.
调用:
函数定义,只是声明了一个函数,它不会被执行,需要调用.
调用的方式,就是函数名加上小括号,括号内写上参数.
调用时写的参数是实际参数,是实实在在传入的值,简称实参.
函数举例:
def add(x, y):
result = x + y
return result
out = add(4, 5)
print(out) # 9
上面只是一个函数的定义,有一个函数add,接收2个参数.
计算的结果,通过返回值返回.
调用通过函数名add加2个参数,返回值可使用变量接收.
定义需要在调用前,也就是说调用时,已经被定义过了,否则抛异常NameError.
函数参数
参数调用时传入的参数要和定义的个数相匹配(可变参数例外).
位置参数:
def f(x,y,z) 调用使用f(1,3,5).
按照参数定义顺序传入实参.
关键字参数:
def f(x,y,z)调用使用f(x=1,y=3,z=5).
使用形参的名字来出入实参的方式,如果使用了形参名字,那么传参顺序就可以和定义顺序不同.
传参:
f(z=None,y=10,x=[1])
f((1,),z=6,y=4.1)
f(y=5,z=6,2)
要求位置参数必须在关键字参数之前传入,位置参数是按位置对应的.
参数规则: 参数列表参数一般顺序是,普通参数,缺省参数,可变位置参数,keyword-only参数(可带缺省值),可变关键字参数.
def fn(x,y,z=3,*arg,m=4,n,**kwargs):
print(x,y,z,m,n)
print(args)
print(kwargs)
函数参数默认值
参数默认值:
定义时,在形参后跟上一个值.
def add(x=4,y=5):
result = x + y
print(result)
add(6,10)
add(6,y=7)
add(x=5)
add()
add(y=7)
# add(x=5,6) # error.
# add(y=8,4) # error.
add(x=5,y=6)
add(y=5,x=6)
注: def add(x=4, y)是错误的.
作用:
参数的默认值可以在未传入足够的实参的时候,对没有给定的参数赋值为默认值.
参数非常多时,并不需要用户每次都输入所有的参数,简化函数调用.
举例:
定义一个函数login,参数名称为host,port,username,password.
def login(host='127.0.0.1', port='8080', username='ames', password='ames'):
print('{}:{}@{}/{}'.format(host, port, username, password))
login()
login('127.0.0.1', 80, 'tom', 'tom')
login('127.0.0.1', username='root')
login('localhost', port=80, password=1234)
login(port=80,password='python', host='www')
# 运行结果:
127.0.0.1:8080@ames/ames
127.0.0.1:80@tom/tom
127.0.0.1:8080@root/ames
localhost:80@ames/1234
www:80@ames/python
可变参数
一个形参可以匹配任意个参数.
def add(nums):
sum=0
for x in nums:
sum += x
return sum
add([1, 3, 5])#9
add([2, 4, 6])#12
位置参数的可变参数: 有多个数,需要累加求和.
def add(*nums):
sum = 0
print(type(nums))
for x in nums:
sum += x
print(sum)
add(3, 6, 9)
<class 'tuple'>
#18
在形参前使用*表示该形参是可变参数,可以接收多个实参.
收集多个实参为一个tuple.
关键字参数的可变参数:
def showconfig(**kwargs):
for k,v in kwargs.items():
print('{} = {}'.format(k,v))
showconfig(host='127.0.0.1', port=8080, username='ames', password=123456)
# 运行结果:
password = 123456
port = 8080
username = ames
host = 127.0.0.1
形参前使用**符号,表示可以接收多个关键字参数.
收集的实参名称和值组成一个字典.
可变参数混合使用:
def showconfig(username,password,**kwargs)
def showconfig(username,*args,**kwargs)
def showconfig(username,password,**kwargs,*args)
总结:
可变参数分为位置可变参数和关键字可变参数.
位置可变参数在形参前使用一个星号*.
关键字可变参数在形参前使用两个星号**.
位置可变参数和关键字可变参数都可以收集若干个实参,位置可变参数收集形成一个tuple,关键字可变参数收集形成一个dict.
混合使用参数时,可变参数要放在参数列表的最后,普通参数需要放到参数列表前面,位置可变参数需要放在关键字可变参数之前.
可变参数举例:
def fn(x,y,*args,**kwargs):
print(x)
print(y)
print(args)
print(kwargs)
fn(3,5,7,9,10,a=1,b='ames')
3
5
(7, 9, 10)
{'a': 1, 'b': 'ames'}
fn(13,15)
13
15
()
{}
fn(23,25,27)
23
25
(27,)
{}
fn(33,35,a=1,b='ames')
33
35
()
{'a': 1, 'b': 'ames'}
fn(7,9,y=5,x=3,a=1,b='ames')
#TypeError: fn() got multiple values for argument 'y' # 错误,7和9分别赋给了x,y,又y=5 x=3,x和y的值重复.
def fn(*args, x, y, **kwargs):
print(x)
print(y)
print(args)
print(kwargs)
fn(3, 5)
#TypeError: fn() missing 2 required keyword-only arguments: 'x' and 'y'
fn(13, 15, 17)
#TypeError: fn() missing 2 required keyword-only arguments: 'x' and 'y'
fn(23, 25, a=1, b='ames')
#TypeError: fn() missing 2 required keyword-only arguments: 'x' and 'y'
fn(37, 39, y=35, x=33, a=1, b='ames')
33
35
(37, 39)
{'a': 1, 'b': 'ames'}
keyword-only参数
keyword-only参数 (python3加入).
如果在一个星号参数后,或者一个位置可变参数后,出现的普通参数,实际上已经不是普通的参数,而是keyword-only参数.
def fn(*args, x):
print(x)
print(args)
fn(3, 5)
#TypeError: fn() missing 1 required keyword-only argument: 'x'
fn(13, 15, 17)
#TypeError: fn() missing 1 required keyword-only argument: 'x'
fn(23, 25, x = 27)
27
(23, 25)
注: 如上错误,args可看做已经截获了所有位置参数,x不使用关键字参数就不可能拿到实参.
以上函数如果换成def fn(**kwargs,x),会直接报语法错误,可以理解为kwargs会截获所有的关键字,就算写了x=5,x也永远得不到这个值,所以语法错误.
keyword-only参数的另一种形式:
def fn(*,x,y):
print(x,y)
fn(x=5,y=6)
5 6
*号之后,普通形参都变成了必须给出的keyword-only参数.
可变参数和参数默认值
def fn(*args,x=5):
print(x)
print(args)
fn() # 等价于fn(x=5)
5
()
fn(5)
5
(5,)
fn(x=6)
6
()
fn(1,2,3,x=10)
10
(1, 2, 3)
def fn(y,*args,x=5):
print('x={},y={}'.format(x,y))
print(args)
fn()
#TypeError: fn() missing 1 required positional argument: 'y'
fn(5)
x=5,y=5
()
fn(x=6)
#TypeError: fn() missing 1 required positional argument: 'y'
fn(1,2,3,x=10)
#x=10,y=1
(2, 3)
fn(y=17,2,3,x=10)
# File "<ipython-input-35-717813843388>", line 1
fn(y=17,2,3,x=10)
^
#SyntaxError: positional argument follows keyword argument
fn(17,2,3,x=10)
x=10,y=17
(2, 3)
fn(1,2,y=3,x=10)
#TypeError: fn() got multiple values for argument 'y'
def fn(x=5, **kwargs):
print('x={}'.format(x))
print(kwargs)
fn()
x=5
{}
fn(5)
x=5
{}
fn(x=6)
x=6
{}
fn(y=3,x=10)
x=10
{'y': 3}
fn(3,y=10)
x=3
{'y': 10}
参数解构
参数解构:
给函数提供实参时,可在集群类型前使用*或**,把集群类型的解构解开,提取出所有元素作为函数的实参.
非字典类型使用*解构成位置参数.
字典类型使用**解构成关键字参数.
提取出来的元素数目要和参数的要求匹配,也要和参数的类型匹配.
def add(x,y):
return x+y
add(*(4,5))
9
add(*[4,5])
9
add(*{4,6})
10
d = {'x':5, 'y':6}
add(**d)
11
add(**{'x':5, 'y':6}
11
def add(*iterable):
result = 0
for x in iterable:
result += x
return result
add(1,2,3)
6
add(*[1,2,3])
6
add(*range(10))
45
练习:
1.编写一个函数,能够接受至少2个参数,返回最小值和最大值.
import random
def double_values(*nums):
print(nums)
return max(nums), min(nums)
print(*double_values(*[random.randint(10, 20) for _ in range(10)])) # 两次解构
# 运行结果:
(18, 16, 16, 12, 13, 13, 14, 20, 18, 16)
20 12
编写一个函数,接受一个参数n,n为正整数,左右两种打印方式.要求数字必须对齐.
def show(n):
tail = ' '.join([str(i) for i in range(n, 0, -1)])
width = len(tail)
for i in range(1, n):
print("{:{}}".format(" ".join([str(j) for j in range(i, 0, -1)]),width))
print(tail)
show(12)
def showtail(n):
tail = ' '.join([str(i) for i in range(n, 0, -1)])
print(tail)
for i in range(len(tail)):
if tail[i] == ' ':
print(' '*i, tail[i+1:])
showtail(12)
def showplus(x):
print(x)
return x+1
print(x+1) # 该行不会执行.
print(showplus(5))
# 运行结果:
5
6
多条return语句:
def guess(x):
if x > 3:
return '>3'
else:
return '<=3'
print(guess(10))
def showplus(x):
print(x)
return x+1
return x+2 # 该行不会执行.
print(showplus(5))
# 运行结果:
5
6
def fn(x):
for i in range(x):
if i > 3:
return i
else:
print('{} is not greater than 3'.format(x))
print(fn(5)) # 运行结果: 4
print(fn(3))
# 运行结果:
3 is not greater than 3
None # 所有函数都有函数值,如果没有return语句,隐式调用return None.
总结:
python函数使用return语句返回'返回值'.
所有函数都有函数值,如果没有return语句,隐式调用return None.
return语句并不一定是函数的语句块的最后一条语句.
一个函数可以存在多个return语句,但是只有一条可以被执行.如果没有一条return语句被执行到,隐式调用return None.
如果有必要,可以显示调用return None,可以简写为return.
如果函数执行了return语句,函数就会返回,当前被执行的return语句之后的其他语句就不会被执行.
作用: 结束函数调用和返回值.
返回多个值:
def showlist():
return [1, 3, 5]
print(showlist()) # 运行结果: [1, 3, 5]
def showlist():
return 1, 3, 5
print(showlist()) # 运行结果: (1, 3, 5)
注:
函数不能同时返回多个值.
return [1,3,5] 即指明返回一个列表,是一个list对象.
return 1,3,5 看似返回多个值,隐式的被python封装成了一个元组.
def showlist():
return 1,3,5
x, y, z = showlist()
print(x, y, z) # 运行结果: 1 3 5
函数嵌套
函数嵌套:
在一个函数中定义了另一个函数.
def outer():
def inner():
print('inner')
print('outer')
inner()
outer()
outer
inner
inner()
#NameError: name 'inner' is not defined
注:
函数有可见范围,这就是作用域的概念.
内部函数不能被外部直接使用,会抛异常NameError,如上代码.
def outer():
def inner():
print('inner')
return 'xx' # return None
print('outer')
inner()
return inner(),'p'
print(outer())
# 执行结果
outer
inner
inner
('xx', 'p') # 两次return的结果组成了一个元组.
作用域
作用域: 一个标识符的可见范围即标识符的作用域.一般常说的是变量的作用域.
x = 5
def foo():
print(x)
foo()
5
x = 5
def foo():
x += 1 # x = x + 1
print(x)
foo()
# 运行报错:
UnboundLocalError: local variable 'x' referenced before assignment
全局作用域:
在整个程序运行环境中都可见.
局部作用域:
在函数,类等内部可见.
局部变量使用范围不能超过其所在的局部作用域.
def fn1():
x = 1 # 局部作用域,在fn1内.
def fn2():
print(x)
print(x)
#NameError: name 'x' is not defined
嵌套结构:
def outer1():
o = 65
def inner():
print('inner {}'.format(o))
print(chr(o))
print('outer {}'.format(o))
inner()
outer1()
# 运行结果:
outer 65
inner 65
A
def outer2():
o = 65
def inner():
o = 97
print('inner {}'.format(o))
print(chr(o))
print('outer {}'.format(o))
inner()
outer2()
# 运行结果:
outer 65
inner 97
a
从嵌套结构例子看出:
外层变量作用域在内层作用域可见.
内层作用域inner中,如果定义了o=97,相当于当前作用域中重新定义了一个新的变量o,但是这个o并没有覆盖外层作用域outer中的o.
x = 5
def foo():
y = x + 1
x += 1
print(x)
foo()
#UnboundLocalError: local variable 'x' referenced before assignment
def foo():
y = x + 1
# x += 1
print(x)
foo()
5
x = 5
def foo():
x += 1
return x
foo()
#UnboundLocalError: local variable 'x' referenced before assignment
注意:
x += 1 其实是 x = x + 1
相当于在foo内部定义一个局部变量x,那么foo内部所有x都是这个局部变量x了.
但是这个x还没完成复制,就被右边拿来做加1操作了,故报错.
全局变量: global
x = 5
def foo():
global x
x += 1
return x
foo()
6
使用global关键字的变量,将foo内的x声明为使用外部的全局作用域中定义的x.
全局作用域中必须有x的定义.
如果全局作用域中没有x定义:
def foo():
global x
x = 10
x += 1
print(x)
foo()
11
print(x)
11
使用global关键字的变量,将foo内的x声明为使用外部的全局作用域中定义的x.
但是,x = 10赋值即定义,x在内部作用域为一个外部作用域的变量赋值,所以x += 1不会报错.注意这里的x的作用域还是全局的.
global总结:
x+=1这种是特殊形式产生的错误的原因,先引用后赋值,而python动态语言是赋值才算定义,才能被引用.解决办法是在这条语句前增加x=0之类的赋值语句,或者使用global告诉内部作用域,去全局作用域查找变量定义.
内部作用域使用x=5之类的赋值语句会重新定义局部作用域使用的变量x,但是一旦这个作用域中使用的global声明为全局的,那么x=5相当于在为全局作用域的变量x赋值.
global使用原则:
外部作用域变量在内部作用域可见,但也不要在这个内部的局部作用域中直接使用,因为函数的目的就是为了封装,尽量与外界隔离.
如果函数需要使用外部全局变量,使用函数的形参传参解决.
函数值传递和引用传递(包括形式参数和实际参数的区别)
通常情况下,定义函数时都会选择有参数的函数形式,函数参数的作用是传递数据给函数,令其对接收的数据做具体的操作处理。在使用函数时,经常会用到形式参数(简称“形参”)和实际参数(简称“实参”),二者都叫参数,之间的区别是:
· 形式参数:在定义函数时,函数名后面括号中的参数就是形式参数,例如:
#定义函数时,这里的函数参数 obj 就是形式参数
def demo(obj)
print(obj)
·
· 实际参数:在调用函数时,函数名后面括号中的参数称为实际参数,也就是函数的调用者给函数的参数。例如:
a = "C语言中文网"
#调用已经定义好的 demo 函数,此时传入的函数参数 a 就是实际参数
demo(a)
·
实参和形参的区别,就如同剧本选主角,剧本中的角色相当于形参,而演角色的演员就相当于实参。
明白了什么是形参和实参后,再来想一个问题,那就是实参是如何传递给形参的呢?Python 中,根据实际参数的类型不同,函数参数的传递方式可分为 2 种,分别为值传递和引用(地址)传递:
1. 值传递:适用于实参类型为不可变类型(字符串、数字、元组);
2. 引用(地址)传递:适用于实参类型为可变类型(列表,字典);
值传递和引用传递的区别是,函数参数进行值传递后,若形参的值发生改变,不会影响实参的值;而函数参数继续引用传递后,改变形参的值,实参的值也会一同改变。例如,定义一个名为 demo 的函数,分别为传入一个字符串类型的变量(代表值传递)和列表类型的变量(代表引用传递):
def demo(obj) :
obj += obj
print("形参值为:",obj)
print("-------值传递-----")
a = "C语言中文网"
print("a的值为:",a)
demo(a)
print("实参值为:",a)
print("-----引用传递-----")
a = [1,2,3]
print("a的值为:",a)
demo(a)
print("实参值为:",a)
运行结果为:
-------值传递-----
a的值为:C语言中文网
形参值为:C语言中文网C语言中文网
实参值为:C语言中文网
-----引用传递-----
a的值为:[1, 2, 3]
形参值为:[1, 2, 3, 1, 2, 3]
实参值为:[1, 2, 3, 1, 2, 3]
分析运行结果不难看出,在执行值传递时,改变形式参数的值,实际参数并不会发生改变;而在进行引用传递时,改变形式参数的值,实际参数也会发生同样的改变。
什么是位置参数,Python位置参数
位置参数,有时也称必备参数,指的是必须按照正确的顺序将实际参数传到函数中,换句话说,调用函数时传入实际参数的数量和位置都必须和定义函数时保持一致。
实参和形参数量必须一致
在调用函数,指定的实际参数的数量,必须和形式参数的数量一致(传多传少都不行),否则 Python 解释器会抛出 TypeError 异常,并提示缺少必要的位置参数。
例如:
def girth(width , height):
return 2 * (width + height)
#调用函数时,必须传递 2 个参数,否则会引发错误
print(girth(3))
#TypeError: girth() missing 1 required positional argument: 'height'
可以看到,抛出的异常类型为 TypeError,具体是指 girth() 函数缺少一个必要的 height 参数。
同样,多传参数也会抛出异常:
def girth(width , height):
return 2 * (width + height)
#调用函数时,必须传递 2 个参数,否则会引发错误
print(girth(3,2,4))
运行结果为:
Traceback (most recent call last):
File "C:\Users\mengma\Desktop\1.py", line 4, in <module>
print(girth(3,2,4))
TypeError: girth() takes 2 positional arguments but 3 were given
通过 TypeErroe 异常信息可以知道,girth() 函数本只需要 2 个参数,但是却传入了 3 个参数。
实参和形参位置必须一致
在调用函数时,传入实际参数的位置必须和形式参数位置一一对应,否则会产生以下 2 种结果:
抛出 TypeError 异常
当实际参数类型和形式参数类型不一致,并且在函数种,这两种类型之间不能正常转换,此时就会抛出 TypeError 异常。
例如:输出结果为:
Traceback (most recent call last):
File "C:\Users\mengma\Desktop\1.py", line 3, in <module>
print(area("C语言中文网",3))
File "C:\Users\mengma\Desktop\1.py", line 2, in area
return height*width/2
TypeError: unsupported operand type(s) for /: 'str' and 'int'以上显示的异常信息,就是因为字符串类型和整形数值做除法运算。
产生的结果和预期不符
调用函数时,如果指定的实际参数和形式参数的位置不一致,但它们的数据类型相同,那么程序将不会抛出异常,只不过导致运行结果和预期不符。
例如,设计一个求梯形面积的函数,并利用此函数求上底为 4cm,下底为 3cm,高为 5cm 的梯形的面积。但如果交互高和下低参数的传入位置,计算结果将导致错误:运行结果为:
正确结果为:17.5
错误结果为:13.5因此,在调用函数时,一定要确定好位置,否则很有可能产生类似示例中的这类错误,还不容易发现。
def area(height,width):
return height*width/2
print(area("C语言中文网",3))
def area(upper_base,lower_bottom,height):
return (upper_base+lower_bottom)*height/2
print("正确结果为:",area(4,3,5))
print("错误结果为:",area(4,5,3))
在函数调用时:位置形参、位置实参、关键字实参的特点
'''形参
在函数定义阶段括号内定义的参数,称之为形式参数,简称形参,
相当于变量名。'''
def func(x,y):
if x > y:
print(x)
print(y)
'''实参
在函数调用阶段括号内传入的参数,称之为实际参数,简称实参,
相当于变量的值。'''func(1,2)'''
位置参数
位置形参:在函数定义阶段,按照从左到右的顺序依次定义的形参, 称之为位置形参。特点:按照位置定义的形参,都必须被传值,多一个不行,少一个也不行。
位置实参:在函数调用阶段,按照从左到右的顺序依次定义的实参, 称之为位置实参。特点:按照位置为对应的形参依次传值。
''''''关键字实参 在调用函数时,按照key=value的形式为指定的参数传值, 称为关键字实参。
func(y=2,x=6) 特点:可以打破位置的限制,但仍然能够为指定的形参赋值。注意注意!!!!!:1、可以混用位置实参和关键字实参,但是位置实参必须在关键字实参的左边。2、可以混用为位置实参和关键字实参,但不能对一个形参重复赋值。
func(x,y=2) #正确
func(y=2,x) #SyntaxError: positional argument follows keyword argument
func(x,x=1) #NameError: name 'x' is not defined
'''func(1,y=2) #正确
# func(y=2,1)
#SyntaxError: positional argument follows keyword argument
# func(1,x=1)
#TypeError: func() got multiple values for argument 'x'
Python匿名函数详解
在编程语言中,函数的应用:
1. 代码块重复,这时候必须考虑用到函数,降低程序的冗余度
2. 代码块复杂,这时候可以考虑用到函数,降低程序的可读性
在Python,有两种函数,一种是def定义,一种是lambda函数
#假如要求两个数之和,用普通函数或匿名函数如下:
1. def func(x,y):
return x+y
2. lambda x,y: x+y
匿名函数(lambda)一般应用于函数式编程中,举个简单例子也许比较好理解,对于一个列表,要求大于3的元素.
过程式编程实现: 也就是常规的方法
L1 = [1,2,3,4,5]
L2 = []
for i in L1:
if i>3:
L2.append(i)
print(L2)
[4, 5]
函数式编程实现: 运用filter,给其一个判断条件即可
def func(x):
return x>3 #在函数中
filter(func,[1,2,3,4,5])
[4, 5]
如果运用匿名函数,则更加精简,一行就可以了:
filter(lambda x:x>3,[1,2,3,4,5])
[4, 5]
总结: 从中可以看出,lambda一般应用于函数式编程,代码简洁,常和reduce,filter等函数结合使用。
格式如下:
解构上面的例子
x 为lambda函数的一个参数
:分割符
x>3 则是返回值,在lambda函数中不能有return,其实:后面就是返回值
为什么要用匿名函数?
1. 程序一次行使用,所以不需要定义函数名,节省内存中变量定义空间
2. 如果想让程序更加简洁时。
匿名函数几个规则:
1. 一般也就一行表达式,必须有返回值
2. 不能有return
3. 可以没有参数,可以有一个或多个参数
def func(x):
x+y
func
#<function func at 0x0000000002F48DD8>
lambda x: x+y
#<function <lambda> at 0x0000000002F48D68>
无参匿名函数:
t = lambda : True #分号前无任何参数
t()
True
等价于下面的def定义的函数
def func():
return True
func()
True
s = "this is\na\ttest" #建此字符串按照正常情形输出
print(s)
'this is\na\ttest'
print (s.split()) #split函数默认分割:空格,换行符,TAB
['this', 'is', 'a', 'test']
' '.join(s.split()) #用join函数转一个列表为字符串
'this is a test'
等价于
(lambda s:' '.join(s.split()))("this is\na\ttest")
带参数匿名函数
lambda x: x**3 #一个参数
lambda x,y,z:x+y+z #多个参数
lambda x,y=3: x*y #允许参数存在默认值
匿名函数调用
#直接赋值给一个变量,然后再像一般函数调用
c = lambda x,y,z: x*y*z
print(c(2,3,4))
24
c = lambda x,y=2: x+y #使用了默认值
c(10) #不输的话,使用默认值2
12
a = lambda *z:z #*z返回的是一个元祖
a('Testing1','Testing2')
('Testing1', 'Testing2')
c = lambda **Arg: Arg #arg返回的是一个字典
c()
{}
#直接后面传递实参
(lambda x,y: x if x> y else y)(101,102)
102
(lambda x:x**2)(3)
9
#lambda返回的值,结合map,filter,reduce使用
filter(lambda x:x%3==0,[1,2,3,4,5,6])
[3, 6]
等价于下面的列表推导式
l = [x for x in [1,2,3,4,5,6] if x%3==0]
l
[3, 6]
嵌套使用
#lambda嵌套到普通函数中,lambda函数本身做为return的值
def increment(n):
return lambda x: x+n
f=increment(4)
f(2)
6
def say():
title = 'Sir,'
action= lambda x: title + x
return action
act = say()
act('Smith!')
'Sir,Smith!'
大量例子:
例01: 字符串联合,有默认值,也可以x=(lambda...)这种格式
>>> x = (lambda x="Boo",y="Too",z="Zoo": x+y+z)
>>> x("Foo")
'FooTooZoo'
例02: 和列表联合使用
L = [lambda x:x**2,\
lambda x:x**3,\
lambda x:x**4]
for f in L:
print f(2)
4
8
16
也可以如下面这样调用
>>> print L[0](3)
9
例03: 和字典结合使用
key = 'B'
dic = { 'A': lambda: 2*2,\
'B': lambda: 2*4,\
'C': lambda: 2*8}
dic[key]()
8
例04: 求最小值
>>> lower = lambda x,y: x if x<y else y
>>> lower('aa','ab')
'aa'
例05: 和map及list联合使用
import sys
showall = lambda x:list(map(sys.stdout.write,x))
showall(['Jerry\n','Sherry\n','Alice\n'])
Jerry
Sherry
Alice
showall(['Jerry','Sherry','Alice'])
JerrySherryAlice
等价于下面
showall = lambda x: [sys.stdout.write(line) for line in x]
showall(('I\t','Love\t','You!'))
I Love You![None, None, None]
例06: 在Tkinter中定义内联的callback函数
import sys
from Tkinter import Button,mainloop
x = Button(text='Press me',
command=(lambda:sys.stdout.write('Hello,World\n')))
x.pack()
x.mainloop()
Hello,World!
Hello,World!
例07: lambda和map联合使用
out = lambda *x: sys.stdout.write(' '.join(map(str,x)))
out('This','is','a','book!\n')
This is a book!
例08: 判断字符串是否以某个字母开头
print (lambda x: x.startswith('B'))('Bob')
True
Names = ['Anne', 'Amy', 'Bob', 'David', 'Carrie', 'Barbara', 'Zach']
B_Name= filter(lambda x: x.startswith('B'),Names)
B_Name
['Bob', 'Barbara']
例09: lambda和map联合使用:
squares = map(lambda x:x**2,range(5))
squares
[0, 1, 4, 9, 16]
例10. lambda和map,filter联合使用:
squares = map(lambda x:x**2,range(10))
filters = filter(lambda x:x>5 and x<50,squares)
filters
[9, 16, 25, 36, 49]
例11. lambda和sorted联合使用
#按death名单里面,按年龄来排序
#匿名函数的值返回给key,进来排序
death = [ ('James',32),
('Alies',20),
('Wendy',25)]
sorted(death,key=lambda age:age[1]) #按照第二个元素,索引为1排序
[('Alies', 20), ('Wendy', 25), ('James', 32)]
例12. lambda和reduce联合使用
L = [1,2,3,4]
sum = reduce(lambda x,y:x+y,L)
sum
10
例13. 求2-50之间的素数
#素数:只能被1或被自己整除的数
nums = range(2,50)
for i in nums:
nums = filter(lambda x:x==i or x % i,nums)
nums
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
例14. 求两个列表元素的和
a = [1,2,3,4]
b = [5,6,7,8]
map(lambda x,y:x+y, a,b)
[6, 8, 10, 12]
例15. 求字符串每个单词的长度
sentence = "Welcome To Beijing!"
words = sentence.split()
lengths = map(lambda x:len(x),words)
>>> lengths
[7, 2, 8]
写成一行:
print map(lambda x:len(x),'Welcome To Beijing!'.split())
python无参函数
'''
#-----------定义函数----------
def func1():
"test1"
print('in the func1')
return 0
#-----------定义过程----------
def func2():
"test2"
print('in the func2')
#-----如何调用----- # 过程其实就是没有返回值的函数
x=func1()
y=func2()
print("from func1 return is:%s"%x)
print("from func2 return is:%s"%y) #在调用没有返回值的func2时,python自动加入了隐式的返回值none
#-----------函数优点----------
def logger(): #优点:1-减少重复代码
with open('test_3','a') as f: # 2-保持函数调用一致性
f.write("end action\n") # 3-高扩展性
def log1():
print("in log1")
logger()
def log2():
print("in log2")
logger()
def log3():
print("in log3")
logger()
log1()
log2()
log3()
#-----------返回值----------
def func1():
print("in func1")
def func2():
print("in func2")
return 0
def func3():
print("in func3")
return 1,'zhangyu',["honey","swallow"],{1:'octopus'} #注:虽然看上去返回了多个值
a=func1() #但实际上是将所有值放入了一个元组进行返回
b=func2() #因此还算是只返回了一个值
c=func3() #总结:
print(a) #返回值数=0:返回None
print(b) #返回值数=1:返回object
print(c) #返回值数>1:返回tuple
'''
python有参函数
def greetings(x='Good morning!'):
print(x)
greetings() # Good morning!
greetings("What's up!") # What's up!
a = greetings() # 返回值是None
def create_a_list(x, y=2, z=3): # 默认参数项必须放后面
return [x, y, z]
b = create_a_list(1) # [1, 2, 3]
c = create_a_list(3, 3) # [3, 2, 3]
d = create_a_list(6, 7, 8) # [6, 7, 8]
def traverse_args(*args):
for arg in args:
print(arg)
traverse_args(1, 2, 3) # 依次打印1, 2, 3
traverse_args('A', 'B', 'C', 'D') # 依次打印A, B, C, D
def traverse_kargs(**kwargs):
for k, v in kwargs.items():
print(k, v)
traverse_kargs(x=3, y=4, z=5) # 依次打印('x', 3), ('y', 4), ('z', 5)
traverse_kargs(fighter1='Fedor', fighter2='Randleman')
def foo(x, y, *args, **kwargs):
print(x, y)
print(args)
print(kwargs)
# 第一个pring输出(1, 2)
# 第二个print输出(3, 4, 5)
# 第三个print输出{'a': 3, 'b': 'bar'}
foo(1, 2, 3, 4, 5, a=6, b='bar')
其实和很多语言差不多,括号里面定义参数,参数可以有默认值,
且默认值不能在无默认值参数之前。
Python中的返回值用return定义,如果没有定义返回值,默认返回值是None。
参数的定义可以非常灵活,可以有定义好的固定参数,
也可以有可变长的参数(args: arguments)和关键字参数(kargs: keyword arguments)。如果要把这些参数都混用,则固定参数在最前,关键字参数在最后。

添加 家长论坛微信
全部 0条评论