python初识day3

本节内容:

  • 函数的基本语法及特性
  • 参数与局部变量
  • 返回值
  • 嵌套函数(important)
  • 递归
  • 匿名函数
  • 函数式编程
  • 高阶函数
  • 内置函数


一、函数的基本语法及特性

定义:函数是指将一组语句的集合通过一个名字(函数名)分装起来,要想执行这个函数,只需调用其函数名即可!

特性(作用):

  • 减少重复代码
  • 使程序变得可扩展
  • 是程序变得易维护

语法定义:

1 def hello(): #函数名
2     print(“hello world!”)
3 
4 hello()#调用函数

  带参数的样式:

 1 #这里实现的时:x的y次方
 2 
 3 #以前是这么写的:
 4 x,y = 2,3
 5 c = x**y
 6 print(c)
 7 
 8 
 9 #用函数写是这么写滴:
10 def numl(x, y):
11     res = x**y
12     return num #返回函数执行结果
13 a,b = 2,3
14 c = (a,b) #结果赋值给c变量
15 print(c)


二、函数参数与局部变量

形参:变量只有在只有在呗调用时才分配内存单元,再调用结束时,立马释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后,就不能再使用改形参变量。

实参:可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些之传送给形参。所以应预先用赋值、输入等办法使参数获得确定的值。

1 #还是刚刚的例子:
2 def num(x, y):#这里的x,y就是形参
3     res = x**y
4     return num 
5 a,b = 2,3
6 
7 
8 c = (a,b) #这里的a,b就是实参
9 print(c)  

 默认参数

  举个栗子

扫描二维码关注公众号,回复: 2386745 查看本文章
def register(name,age,sex,classes):
    print("————安全1601班学生入学登记————")
    print("姓名",name)
    print("年龄",age)
    print("性别",sex)
    print("班级",classes)

register("赔肥肥",26,"","安全1601")
register("木子园",28,"女","安全1601")
register("月月鸟",17,"","安全1601")
register("马铁棍",37,"女","安全1601")
register("文刀璟",55,"","安全1601")

很明显class这个参数都是"安全1601",就像注册qq或者注册邮箱时,国籍这一项基本默认的都是中国,是不用填写的,这就是通过默认参数实现的,把class变成默认参数非常简单

def register(name,age,sex,classes="安全1601")
    #下面和上一个代码一样写

小提示:在写默认参数时最好把默认参数放最后。


 非固定参数

若你的函数在定义时不确定用户想传入多少个参数,就可以使用非固定参数

 1 def register(name,age,*args):# *args 会把多传入的参数变成一个元组形式
 2     print(name,age,args)
 3 
 4 
 5 register("木子主",18)
 6 #输出
 7 #木子主 18 ()  #后边这个()就是args,只是用户并没用传进去值,所以是空的元组
 8 
 9 register("赔肥肥",19,"","安全1601")
10 #输出
11 #赔肥肥 19 ('男', '安全1601')

还有一个**kwargs

 1 def register(name,age, *args, **kwargs):# *kwargs 会把多传入的带等号的参数变成一个字典形式
 2     print(name, age, args, kwargs)
 3 
 4 register("月月鸟",20,"","喜欢篮球")
 5 #输出
 6 #月月鸟 20 ('女', '喜欢篮球') {}  #最后空的{}就是**kwargs,因为没有传值所以为空。
 7 
 8 
 9 
10 register("月月鸟",20,"","喜欢篮球",city="深圳",classes ="安全1601")
11 #输出
12 #月月鸟 20 ('女', '喜欢篮球') {'city': '深圳', 'classes': '安全1601'}

注意:在传一个多余的带等号的值后(也就是**kwargs有值后),就不能给*args传值。

例如:register("月月鸟",20,"女","喜欢篮球",city="深圳",classes ="安全1601","帅"),这个"帅",就会导致报错。


 局部变量

gevent = "木子圆喜欢肥肥"

def haha(gevent):
    print(gevent)
    gevent ="马铁棍喜欢文刀景"
    print(gevent)

haha(gevent)

print(gevent)
#输出 #木子圆喜欢肥肥 #马铁棍喜欢文刀景 #木子圆喜欢肥肥

由此可以看出gevent在函数内被改变时,制作用在函数内,一但程序执行完函数,gevent有还原回原来的值。

全局与局部变量

在子程序(例如函数,以及后边面向对象中的类)中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
当全局变量与局部变量同名时:
在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。


三、返回值

要想获取函数的执行结果,就可以用return语句把结果返回

注意: 

  • 函数在执行过程中只要遇到return语句,就会停止执行并返回结果,所以也可以理解为 return 语句代表着函数的结束
  • 如果未在函数中指定return,那这个函数的返回值为None 


四、嵌套函数(important)

def example():
    name = "木子猪1"

    def example2():
        name = "木子猪2"
        print("第三层:",name)

    example2()
    print("第二层:",name)

example()
print("第一层:",name)

#输出
#第三层: 木子猪2
#第二层: 木子猪1
#第一层: 木子猪

小提示:在函数里边嵌套的函数只能在函数体里被调用,试试在外边调用一下啊!试试外边打个example2()



 五、递归

由上可知,在函数内部是可以调用函数的,但是调用的函数如果是自己又会是啥情况呢?——没错就是递归。

def calc(n):
    print(n)
    if int(n/2) ==0:
        return n
    return calc(int(n/2))
 
calc(10)
 
#输出:
#10
#5
#2
#1

 递归特性:

1. 必须有一个明确的结束条件

2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少

3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

递归函数实际应用案例,二分查找

 1 data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
 2  
 3  
 4 def binary_search(dataset,find_num):
 5     print(dataset)
 6  
 7     if len(dataset) >1:
 8         mid = int(len(dataset)/2)
 9         if dataset[mid] == find_num:  #find it
10             print("找到数字",dataset[mid])
11         elif dataset[mid] > find_num :# 找的数在mid左面
12             print("\033[31;1m找的数在mid[%s]左面\033[0m" % dataset[mid])
13             return binary_search(dataset[0:mid], find_num)
14         else:# 找的数在mid右面
15             print("\033[32;1m找的数在mid[%s]右面\033[0m" % dataset[mid])
16             return binary_search(dataset[mid+1:],find_num)
17     else:
18         if dataset[0] == find_num:  #find it
19             print("找到数字啦",dataset[0])
20         else:
21             print("没的分了,要找的数字[%s]不在列表里" % find_num)
22  
23  
24 binary_search(data,66)
View Code


六、匿名函数

匿名函数:为了解决那些功能很简单的需求而设计的一句话函数。

 1 #这段代码
 2 def calc(n):
 3     renturn n**n
 4 
 5 print(calc(10))
 6 
 7 #换成匿名函数
 8 
 9 calc = lambda n:n**n
10 
11 print(calc(10)) 

 

 上面是我们对calc这个匿名函数的分析,下面给出了一个关于匿名函数格式的说明

1 函数名 = lambda 参数 :返回值
2 
3 #参数可以有多个,用逗号隔开
4 #匿名函数不管逻辑多复杂,只能写一行,且逻辑执行后的内容就是返回值
5 #返回值和正常函数一样可以是任意数据类型

我们可以看出,匿名函数并不是真的不能有名字。

匿名函数的调用和正常的调用也没有什么分别。 就是 函数名(参数) 就可以了~~~

匿名函数与内置函数举例:

1 l=[3,2,100,999,213,1111,31121,333]
2 print(max(l))
3 
4 dic={'k1':10,'k2':100,'k3':30}
5 
6 
7 print(max(dic))
8 print(dic[max(dic,key=lambda k:dic[k])]


七、函数式编程介绍

函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。

函数式编程中的函数这个术语不是指计算机中的函数(实际上是Subroutine),而是指数学中的函数,即自变量的映射。也就是说一个函数的值仅决定于函数参数的值,不依赖其他状态。比如sqrt(x)函数计算x的平方根,只要x不变,不论什么时候调用,调用几次,值都是不变的。

 Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。

定义:

简单说,"函数式编程"是一种“编程规范”(programming paradigm),也就是如何编写程序的方法论。

 主要思想是把运算过程尽量写成一系列嵌套的函数调用。举例来说,现在有这样一个数学表达式:

  (1 + 2) * 3 - 4

传统的过程式编程,可能这样写:

      var a = 1 + 2;

      var b = a * 3;

      var c = b - 4;

函数式编程要求使用函数,我们可以把运算过程定义为不同的函数,然后写成下面这样:

  var result = subtract(multiply(add(1,2), 3), 4);

这段代码再演进以下,可以变成这样

add(1,2).multiply(3).subtract(4)

这基本就是自然语言的表达了。再看下面的代码,大家应该一眼就能明白它的意思吧:

merge([1,2],[3,4]).sort().search("2")

因此,函数式编程的代码更容易理解。

要想学好函数式编程,不要玩py,玩Erlang,Haskell。



八、高阶函数

变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

def add(x,y,f):
    return f(x) + f(y)
 
 
res = add(3,-6,abs)
print(res)


九、内置函数

内置参数详解 https://docs.python.org/3/library/functions.html?highlight=built#ascii



 面试题小总结:

猜你喜欢

转载自www.cnblogs.com/island0603/p/9351164.html