Python全栈开发-Day3-Python基础3
本节内容
1. 函数基本语法及特性
2. 参数与局部变量
3.递归
4.函数式编程介绍
5.高阶函数
1.函数基本语法及特性
三种编程范式:
1、面向过程:过程——> def
2、面向对象:类——> class
3、函数式编程:函数——> def
函数是什么?
函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,编程中的函数在英文中也有很多不同的叫法。在C中只有function,在Java里面叫做method。
定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可
使用函数的好处:
- 减少重复代码
- 使程序变的可扩展
- 使程序变得易维护
语法定义
1
2
3
4
5
|
def test(x): #函数定义方法、函数名、变量 '''The function difinition!''' #对该函数的描述 x+=1 #函数体 return x #返回值
test(1) #调用函数 |
函数:
def func1():
'''testing1'''
print('in the func1')
return 0
过程:
def func2():
'''testing2'''
print('in the func2')
由上得出,过程就是没有返回值的函数。
可以带参数
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#下面这段代码 a,b = 5 , 8 c = a * * b print (c) #改成用函数写 def calc(x,y): res = x * * y return res #返回函数执行结果 c = calc(a,b) #结果赋值给c变量 print (c) |
return的作用
1、终止函数的运行,即return后面的代码都将不会被执行
2、return给调用该函数的位置,返回一个值。如,x=test1(),x就会接收到return的返回值
3、后续程序有时需要根据之前函数return返回值的不同,进行不同的判断和运算。
return的返回值
return 1, 'hello', ['alex','wupeiqi'], {‘name’:'alex'}
所以,return的个数没规定,类型没规定。把return后面的内容放入元组中全部返回,本质上return还是返回了一个值。如果之前有一个函数def test():, 用return test 时,返回值是test函数的内存地址。
2.函数参数与局部变量
调用方法:
1、test()执行,()表示调用函数test,()可以有参数也可以没有
参数
1、形参和实参
形参:形式参数,不是实际存在的,是虚拟变量,在定义函数和函数体的时候使用形参,目的是在函数调用时接收实参(实参个数、类型应与形参一一对应)
实参:实际参数,调用函数时传给函数的参数,可以是常量,变量,表达式,函数,传给形参
区别:形参是虚拟的,不占用内存空间,形参变量只有在被调用时才分配内存单元,实参是一个变量,占用内存空间,数据传送单向,实参传送给形参,不能形参传给实参。
2、关键字调用,与形参顺序无关;位置调用与形参一一对应。
【注意】:关键字参数不能写在位置参数之前
3、默认参数
def test(x,y=2):
print(x,y)
test(1)
上述代码在定义函数时对形参赋值的过程叫做设置默认参数,被赋的值叫做对应形参的默认参数。
默认参数特点:调用函数时,默认参数非必须传递
4、参数组:
1)def test(*args):
print(args)
test(1,2,3,4,5) #或者等价于后面这种赋值方式: test(*[1,2,3,4,5])
输出:(1,2,3,4,5)
这时候会把5个位置实参全部传给形参args,并且以元组的形式保存下来。定义位置调用参数组时,以*开头即可,args的名字可以是任意的。但编写规范就是*args。
2)def test2(**kwargs):
print(kwargs)
test2(name='gavin',age=25,sex='M') #或者等价于后面这种赋值方式: test2(**{‘name’:'gavin','age':25,'sex':'M'})
输出:{‘name’:'gavin','age':25,'sex':'M'}
这时候会把3个关键字调用的实参全部传递给形参kwargs,并且以字典的方式保存,关键字为key,给关键字赋的值为value。定义关键字调用参数组时,以**开头,kwargs的名字可以是任意的,但是编写规范就是**kwargs。
3)小结:
*args把N个位置参数,转换成元组的方式
**kwargs把N个关键字参数,转换成字典的方式
【注意】: 参数组一定要放在形参的最后面
位置参数一定要写在关键字参数之前。所以对应的,形参部分先写*args,再写**kwargs。
局部变量
1
2
3
4
5
6
7
8
9
10
|
name = "Alex Li" def change_name(name): print ( "before change:" ,name) name = "金角大王,一个有Tesla的男人" print ( "after change" , name) change_name(name) print ( "在外面看看name改了么?" ,name) |
输出
1
2
3
|
before change: Alex Li after change 金角大王,一个有Tesla的男人 在外面看看name改了么? Alex Li |
全局与局部变量
在函数内修改全局变量
name=‘gavin
def change_name(name):
global name
name='Gavin Simons'
pass
chang_name(name)
在上述这种情况下,在函数内部使用global指令,声明了name为全局变量,此时在函数内部再修改name时,修改的是全局变量。同时如果在函数内部声明全局变量之前,即在文件开头并没有相同名字的全局变量,则函数内的全局变量会被新创建,在函数外部也可以进行调用。但是,虽然这样可行,但是永远不要这么干(包括在函数内修改全局变量和在函数内创建全局变量),因为这么做很难去调试,不知道是那个函数创建或修改了全局变量。
局部变量和全局变量的特殊情况
names=['Gavin','Simons','Jack','Rain']
def chang_name():
names[0] = ‘詹姆斯西蒙斯’
print('inside func',names)
change_name()
print(names)
输出:inside func ['詹姆斯西蒙斯','Simons','Jack','Rain']
['詹姆斯西蒙斯','Simons','Jack','Rain']
所以只有像简单的数据类型(比如,字符串和整数)是不能在函数中修改的。但是复杂的数据类型(比如,列表、字典、集合、类,元组在什么时候都不能改)这些都是在局部里面可以直接改全局的。因为存放方式和简单数据类型不同,后者存放的是地址,而不是具体的值。
3. 递归
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
堆栈扫盲http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html
递归函数实际应用案例,二分查找
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
data = [ 1 , 3 , 6 , 7 , 9 , 12 , 14 , 16 , 17 , 18 , 20 , 21 , 22 , 23 , 30 , 32 , 33 , 35 ] def binary_search(dataset,find_num): print (dataset) if len (dataset) > 1 : mid = int ( len (dataset) / 2 ) if dataset[mid] = = find_num: #find it print ( "找到数字" ,dataset[mid]) elif dataset[mid] > find_num : # 找的数在mid左面 print ( "\033[31;1m找的数在mid[%s]左面\033[0m" % dataset[mid]) return binary_search(dataset[ 0 :mid], find_num) else : # 找的数在mid右面 print ( "\033[32;1m找的数在mid[%s]右面\033[0m" % dataset[mid]) return binary_search(dataset[mid + 1 :],find_num) else : if dataset[ 0 ] = = find_num: #find it print ( "找到数字啦" ,dataset[ 0 ]) else : print ( "没的分了,要找的数字[%s]不在列表里" % find_num) binary_search(data, 66 ) |
4.函数式编程介绍
函数是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);
因此,函数式编程的代码更容易理解。
要想学好函数式编程,不要玩py,玩Erlang,Haskell。
5.高阶函数
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
即把函数本身当作一个参数,传给另一个函数。
1
2
3
4
5
6
|
def add(x,y,f): #f为一个函数形参 return f(x) + f(y) res = add( 3 , - 6 , abs )#abs是函数实参,其实就是函数abs的内存地址 print (res) |
Python全栈开发-Day3-Python基础3的更多相关文章
- python 全栈开发:python基础
python具有优美.清晰.简单,是一个优秀并广泛使用的语言.诞生于1991年2.python历史 1989年,为了打发圣诞节假期,Guido开始写Python语言的编译器.Python这个名字,来自 ...
- Python 全栈开发四 python基础 函数
一.函数的基本语法和特性 函数的定义 函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的.函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数 ...
- python全栈开发-Day8 函数基础
python全栈开发-Day8 函数 一 .引子 1. 为何要用函数之不用函数的问题 #1.代码的组织结构不清晰,可读性差 #2.遇到重复的功能只能重复编写实现代码,代码冗余 #3.功能需要扩展时,需 ...
- Python 全栈开发二 python基础 字符串 字典 集合
一.字符串 1,在python中,字符串是最为常见的数据类型,一般情况下用引号来创建字符串. >>ch = "wallace" >>ch1 = 'walla ...
- Python全栈开发day3
1.Pycharm使用介绍 1.1 新建py文件自动添加python和编码 1.2 更改pycharm默认字体和风格 点击左上角“file”-->“Settings”(或者用“Ctrl+Alt+ ...
- Python 全栈开发三 python基础 条件与循环
一. 条件语句 python条件语句是根据一条或多条语句的执行结果的真假(True Or False)来决定代码块的执行. 而执行内容可以多行,以缩进来区分表示同一范围. 1.Python判断条件真假 ...
- python全栈开发-Day3 字符串
python全栈开发-Day3 字符串 一.按照以下几个点展开字符串的学习 #一:基本使用 1. 用途 #首先字符串主要作用途径:名字,性别,国籍,地址等描述信息2.定义方式 在单引号\双引号\三引 ...
- Python 全栈开发一 python初识
1.Python简介 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC ...
- Python全栈开发【基础四】
Python全栈开发[基础四] 本节内容: 匿名函数(lambda) 函数式编程(map,filter,reduce) 文件处理 迭代器 三元表达式 列表解析与生成器表达式 生成器 匿名函数 lamb ...
- Python全栈开发【基础三】
Python全栈开发[基础三] 本节内容: 函数(全局与局部变量) 递归 内置函数 函数 一.定义和使用 函数最重要的是减少代码的重用性和增强代码可读性 def 函数名(参数): ... 函数体 . ...
随机推荐
- Linux 使用 github 常用命令
Linux 使用 github 常用命令 今天整理一下常用的 github 命令,自己只是一个编程小白,有些地方可能做的不是很好,仅仅用作自己的学习使用. 创建一个文件夹用于存放github仓库 m ...
- 12: nginx原理及常用配置
1.1 nginx基本介绍 1.nginx高并发原理( 多进程+epoll实现高并发 ) 1. Nginx 在启动后,会有一个 master 进程和多个相互独立的 worker 进程. 2. 每个子进 ...
- javaScript中ajax、axios总结
一.原生js实现ajax请求: 步骤: get请求: // 1.创建一个XMLHttpRequest的对象. var xml=null; //初始值设为空 if(XMLHttpRequest){ xm ...
- 经典算法分析:n^2与nlgn
冒泡.插入.选择排序的时间复杂度为O(n2) Arrays.sort()时间复杂度为nlgn 具体算法实现代码: package recursion; import java.util.Arrays; ...
- 数据库 --- 4 多表查询 ,Navicat工具 , pymysql模块
一.多表查询 1.笛卡儿积 查询 2.连接 语法: ①inner 显示可构成连接的数据 mysql> select employee.id,employee.name,department ...
- 在Ubuntu上更新Chrome到最新的版本
本操作只限于已经安装了Chrome的Ubuntu系统: Step 1: sudo apt-get update Step 2: sudo apt-get install google-chrome-s ...
- Java中Map接口的遍历
package Test4; import java.util.Collection;import java.util.HashMap;import java.util.Iterator;import ...
- Flutter 第一次运行就出现白屏的问题
--enable-software-rendering 解决办法: 顶部菜单找到 run-->Edit Configurations 中加这么一句:
- 使用msi自动安装系统
在实际生活中, 还是要尽量使用 自动化 脚本 等来处理/执行问题, 那样更快更省力省时间 要多使用 网络工具, 网络工具在 管理/ 使用网络的过程 中还是很有用的. 要有这种 "多使用网络工 ...
- 如何安装整个linux系统中所需要的mp3播放库插件? 可以在安装rpmfusion仓库后直接通过dnf install进行按照就可以了
在vi的界面中, 前面的数字, 表示一行. 而对于中文而言, 并不一定是"一个文本行"就是一行, 而是以 回车(硬回车)为标志, 来判定一行的. 而dd, yy等也是以" ...