Python-Task5 函数和lambda表达式

Python-Task5 函数和lambda表达式

学习内容

廖雪峰老师python教程https://www.liaoxuefeng.com/wiki/1016959663602400

小甲鱼python教程:https://www.bilibili.com/video/av27789609?from=search&seid=697360651657412999


函数

调用函数

python支持非常灵活定义的函数,而且本身内置了很多有用的函数。

函数最基本的一种代码抽象方式。

https://docs.python.org/3/library/functions.html

python有提供了很多内置函数,使用方法可以在官网查询。也可以使用help(abs)查看abs函数的帮助文档

TypeError 错误会反应参数错误。

max() and min() 可以有多个参数

函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”

>>> i=int
>>> i(1.2)
1

定义函数

定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。

x=input('your name:')
def my_hello(x):
    return 'hello '+x

print(my_hello(x))

注意,如果没有return 语句,会返回None。return None 简写为return

将my_hello()的函数定义保存为hello.py文件后,在该文件目录下,可以使用 from hello import my_hello ()不需要.py扩展名)可以导入my_hello()函数

>>> from hello import my_hello
>>> my_hello('wenjunjie')
'hello wenjunjie'

空函数:用pass语句作为占位符

数据类型检查可以使用内置函数isinstance()实现;

if not isinstance(x, (int, float)):
        raise TypeError('bad operand type')
函数可以返回多个值!!!

形如 return a,b

实际返回的是一个元祖,但在语法上,返回一个元祖可以省略括号,多个变量可以同时接受一个tuple,按位置赋值给对应的值。

c,d=move(…)

函数的参数

位置参数:形如power(x,y) ,x和y是位置参数。调用函数时,传入的两个值按照位置顺序依次赋给参数x和y。
默认参数:给一些参数赋默认值 power(x,y=2),有两个注意点

1.必选参数在前,默认参数再后

2.变化大的参数放前面,变化小的放在后边

 def enroll(name, gender, age=6, city='Beijing')
 enroll('Bob', 'M', 7)
 enroll('Adam', 'M', city='Tianjin')

定义默认参数要牢记一点:默认参数必须指向不变对象!

可变参数:可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。
def calc(*numbers): #定义,内部来说还是组装了一个元祖
calc(1,2,3,4,5...) #使用
calc(*nums)  #nums是一个list或tuple 当要传入list或者tuple时候在变量前加*
关键字参数:关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
def person(name, age, **kw):    #定义
    print('name:', name, 'age:', age, 'other:', kw)
person('Adam', 45, gender='M', job='Engineer')#使用
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'} #结果
person('Jack', 24, **extra)  #extra为元祖时

**extra表示把extra这个dict的所有key-value用关键字参数传入到函数的**kw参数,kw将获得一个dict,注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra

命名关键字参数:相比关键字参数,命名关键字参数可以显示关键字的名字。
def person(name, age, *, city, job): #定义
    print(name, age, city, job)
person('Jack', 24, city='Beijing', job='Engineer') #调用

命名关键字参数需要一个特殊分隔符**后面的参数被视为命名关键字参数。

命名关键子可以有缺省值(默认值)

参数组合

参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。

对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的。

虽然可以组合多达5种参数,但不要同时使用太多的组合,否则函数接口的可理解性很差

小练习

题目:求一个或多个数的乘积

def product(x,*y):
    ans=x
    for i in y:
        ans=ans*i
    return ans

使用*args**kw是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。

递归函数

函数在内部调用自己本身就是递归函数。逻辑清晰

解决栈溢出的方法,尾递归优化。

尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。

Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。

小练习

汉诺塔问题

def move(n,a,b,c):
    if n==1:
        print(a,'-->',c)
    else:
        move(n-1,a,c,b)
        move(1,a,b,c)
        move(n-1,b,a,c)
move(3, 'A', 'B', 'C')

lambda表达式

>>> def fun1(x):      #一般定义函数
...     return 2*x+1

>>> g=lambda x:2*x+1 #使用lambda表达式

使用lambda表达式的目的

  • 使得代码精简
  • 不需要考虑命名,对于只使用一两次的函数比较友好
  • 简化可读性

补充BIF

filter(function,iterator):过滤器iterator。一次迭代iterator中的元素,该元素经过function,如果返回true加入到结果,否则被过滤掉。

>>> list(filter(lambda x:x%2,range(20)))
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

map(fun,iterator):映射。将iterator中的元素依次作为fun的参数,经过处理的结果加入到结果序列中

>>> list(map(lambda x:x**2,range(10)))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

你可能感兴趣的:(Python,python,学习笔记)