Python之路-函数
一.函数是什么:
python中函数定义:函数是逻辑结构化和过程化的一种编程方法。定义函数的方法为:
def function():
""The function definitions""
do something
return reselut def:定义函数的关键字
function 函数名
()括号内可定义形参或者实参
""可描述函数功能,非必选
结构体:do somethin,完成某种功能
return:将函数结果返回
二.使用函数的好处:
1.减少代码重用
2.保持一致性,易维护。相同功能可以使用同一个函数,功能发生改变时,直接修改函数即可
3.扩展性更好
三.函数的参数(实参,形参,可选参数,默认参数)
1.形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量
2.实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值
def test(a): #a为形参,在函数结构体中起到占位的作用
return a*a test(1) #1为实参
3.位置参数和关键字(标准调用:实参与形参位置一一对应;关键字调用:位置无需固定)
def test(a,b,c,d)
print(a)
print(b)
print(c)
print(d) test(1,d=2,c=3,b=1)
'''
使用关键字传参,可不用注意参数的位置
'''
4.可选参数 *args **kwargs(如果同时存在,**kwargs位置需要在*args后面)
*args以元组的形式传递多个参数
def fun(*args):
print(args)
print(type(args))
fun(1,2,3,4) 结果:
(1, 2, 3, 4)
<class 'tuple'>
**kwargs 以字典的形式传递多个参数,所以参数需要是
def fun(**kwargs):
print(kwargs)
print(type(kwargs))
fun(a=1,b=2,c=3,d=4) 输出结果:
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
<class 'dict'>
5.默认参数
设置好默认参数,如果该形参参数无对应的实参,则使用默认参数
def fun(a='b'):
print(a) fun()
fun('a') 输出结果
b
a
四.局部变量和全局变量
在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
name=123
def fun():
print(name)
fun() 输出结果:
123
2.没有global关键字,则在函数中重新定义了变量,则函数内使用局部变量,全局变量保存不变
name=123
def fun():
name=234
print(name)
fun()
print(name) 输出结果:
234
123
由此可知,函数没有global关键字时,对全局变量只有读的权限,没有重新赋值的权限。需要注意的是:当全局变量为可变数据类型(列表,字典)时,函数是可以进行列表内容的修改。由此可见得,函数无法为全局变量开辟新的内存空间,但是可以对其内存地址存储内容进行修改。
name=[1,2,3,4]
def fun():
name.append(5)
print(name)
fun()
print(name) 输出结果:
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
3.有global关键字,且重新定义了全局变量。则会修改全局变量。
name=123
def fun():
global name
name=234
print(name)
fun()
print(name) 输出结果:
234
234
我们要注意,不能在函数内,global前再定义变量,这样global无法区分你要申请的是全局变量还是 局部变量,会导致报错。
name=234
def fun():
name = 123
global name
print(name)
fun() 报错信息:
SyntaxError: name 'name' is assigned to before global declaration
4.有global关键字,则定义的变量在全局变量中不存在,则创建全局变量。
def fun():
global name
name=234
print(name) def fun1():
print('fun1',name) fun()
fun1() 输出结果:
234
fun1 234
当我们无论在内嵌多少层的函数中使用global时,他都会变为全局变量。在内存中,可理解为:
global在此告一段落,接下来,介绍一下内嵌函数如何使用上层函数的变量。
nonlocal 关键字,定义了内嵌函数使用上层函数的变量
name=234
def fun():
name=1
def fun1():
nonlocal name
print('fun1',name)
fun1()
fun() 输出结果:
fun1 1
如果我们在第一层函数上使用该关键字,则会报错。所以不能在第一层函数使用该关键字。
def func(): #定义函数时,将函数内容以字符串形式保存在内存里
print('test')
return func print('haha') #第一步,执行打印命令
func() #调用函数,将内存中存储的字符串当命令使用
a=func() #将func的内存地址赋值给变量名a
a() #通过a来调用函数func 打印结果:
haha
test
test
test
函数调用前,都需要先将函数内容读取到内存中,再进行调用。和变量一样。我们定义变量时,会先将变量名和内容读取到内容中。当我们在调用变量名时,如果内存中午对应的值,则会报错。
错误示例:
print(name)
name='haha' func()
def func():
print('this is func')
当我们执行函数时,只要函数内容已经存在内存中,则不分它存储的前后顺序。如下示例,虽然在定义函数时,func()调用func1时,func1并未定义,但是执行时func,func1都已经定义好了,故执行未报错。
def func():
print('this is func')
func1() def func1():
print('this is func1') func() 输出结果:
this is func
this is func1
六.递归函数
递归函数:在函数内部,可以调用其他函数。如果在调用一个函数的过程中直接或间接调用自身本身,则是递归函数。
1 def calc(n):
2 print(n)
3 if int(n/2) ==0:
4 return n
5 return calc(int(n/2))
6
7 calc(10)
8
9 输出:
10 10
11 5
12 2
13 1
递归特性:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
由于递归函数的效率性不高,所以可以使用尾部调用来进行调优。即在函数的最后一步进行函数调用(最后一步不一定在最后一行)。这样就可以再调用函数完,即可释放内存。
函数的作用域
函数变量的作用域取决去它所在的内存位置,而不是在代码中所调用的位置。例如:
def scope():
scope_var='this is scope'
def scope1():
scope_var='this is scope1'
scope1()
print(scope_var)
return scope1 var=scope() #scope1 '''
虽然是在主程序中直接调用了scope1函数,但是scope_var='this is scope1'的作用域还是只在scope函数下的scope1函数中,
这是因为python在读取函数定义时,已经按照相应层级读取到内存中。在主程序的调用只是直接调用内存而已
'''
高阶函数
满足俩个特性任意一个即为高阶函数
1.函数的传入参数是一个函数名
2.函数的返回值是一个函数名
map函数
map(func, *iterables) --> map object,处理序列中的每个元素,得到的结果是一个‘列表 ’,该‘列表’元素个数及位置与原来一样。map函数的原理如下:
def map_test(func,list_name):
res=[]
for i in list_name:
res.append(func(i))
return res def add_one(n):
return n*n
test=[1,2,3,4,5]
print(map_test(add_one,test))
可以用lambda来处理对象
print(list(map(lambda x:x+1,[1,2,3,4])))
filter函数
filter(function or None, iterable) --> filter object,遍历序列中的每个元素,判断每个元素的布尔值,如果为Ture,则留下该值。filter的原理如下 :
name=['sb1','sb2','3sb','xb']
def func(item):
return not item.startswith('sb') def filter_test(func,item):
new_list=[]
for i in item:
if func(i):
new_list.append(i)
return new_list print(filter_test(func,nam
可以用lambda来处理对象
list(filter(lambda x:not x.startswith('sb'),name))
reduce函数
reduce(function, sequence[, initial]) -> value,reduce()处理一个序列,然后把序列进行合并操作。原理如下:
def func(res,i):
return res+i
def reduce_test(func,seq,init=None):
if init == None:
res=seq.pop(0)
else:
res=init
for i in seq:
res=func(res,i)
return res
seq=[1,2,3,4,5,6,]
print(reduce_test(func,seq))
用lambda来处理对象
from functools import reduce
seq=[1,2,3,4,5,6,]
print(reduce(lambda x,y:x+y,seq))
内置函数
#abs()
print(abs(-1)) #去绝对值 #all()
print(all([1,'',None])) #判断序列元素布尔值是否都为True,有一个为False,则返回False.空列表,空字符串等返回Ture
print(all('')) #True
print(all([''])) #False #any
print(any([1,'',None])) #判断序列元素布尔值是否都为False,有一个为True,则返回True.空列表,空字符串等返回False
print(any('')) #False
print(any([1,'',None])) #True #bin
bin(12) #将十进制转换为二进制 #bool() 判断bool值
print(bool(0)) #chr 根据序号找到acsii码表对应的字符
print(chr(97)) #ord 根据字符,找出对应的ascii码对应的序号
print(ord('a')) #compile() 将source编译为代码或者AST对象。代码对象能够通过exec语句来执行或者eval()进行求值。 没什么用。忽略 #divmod(x, y) 返回元组(x//y, x%y),即返回商的整数和余数部分
print(divmod(3,2))
字典的运算:最小值,最大值,排序
salaries={
'egon':3000,
'alex':100000000,
'wupeiqi':10000,
'yuanhao':2000
} 迭代字典,取得是key,因而比较的是key的最大和最小值
>>> max(salaries)
'yuanhao'
>>> min(salaries)
'alex' 可以取values,来比较
>>> max(salaries.values())
100000000
>>> min(salaries.values())
2000
但通常我们都是想取出,工资最高的那个人名,即比较的是salaries的值,得到的是键
>>> max(salaries,key=lambda k:salary[k])
'alex'
>>> min(salaries,key=lambda k:salary[k])
'yuanhao' 也可以通过zip的方式实现
salaries_and_names=zip(salaries.values(),salaries.keys()) 先比较值,值相同则比较键
>>> max(salaries_and_names)
(100000000, 'alex') salaries_and_names是迭代器,因而只能访问一次
>>> min(salaries_and_names)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: min() arg is an empty sequence sorted(iterable,key=None,reverse=False)
Python之路-函数的更多相关文章
- python之路——函数进阶
阅读目录 楔子 命名空间和作用域 函数嵌套及作用域链 函数名的本质 闭包 本章小结 楔子 假如有一个函数,实现返回两个数中的较大值: def my_max(x,y): m = x if x> ...
- 百万年薪python之路 -- 函数的动态参数
1.函数的动态参数 1.1 动态接收位置参数 在参数位置用*表示接受任意参数 def eat(*args): print('我想吃',args) eat('蒸羊羔','蒸熊掌','蒸鹿尾儿','烧花鸭 ...
- Python之路-函数基础&局部变量与全局变量&匿名函数&递归函数&高阶函数
一.函数的定义与调用 函数:组织好的.可重复使用的.用户实现单一或者关联功能的代码段.函数能够提高应用的模块性和代码的重复利用率.Python提供了很多内置的函数,比如len等等,另外也可以根据自己的 ...
- python之路函数
1.函数参数,引用 2.lambda表达式 lambda表达式 f1 = lambda a1,a2: a1+a2 3.python的内置函数 abs(),绝对值 all(),循环参数,如果每个元素都为 ...
- 百万年薪python之路 -- 函数名的第一类对象及使用
函数名是一个变量, 但它是一个特殊的变量, 与括号配合可以执行函数的变量 1.1.函数名的内存地址 def func(): print("呵呵") print(func) 结果: ...
- 百万年薪python之路 -- 函数的动态参数练习
1.继续整理函数相关知识点. 2.写函数,接收n个数字,求这些参数数字的和.(动态传参) def func(*args,**kwargs): num_sum = 0 num_dic = [] num ...
- 百万年薪python之路 -- 函数初始
1.函数 1.1 认识函数 定义一个事情或者是功能,等到需要的时候直接去用就好了.那么这里定义东西就是一个函数 函数:对代码块和功能的封装和定义 函数的好处: 减少代码的重复性 代码可读性高 将功能进 ...
- 百万年薪python之路 -- 函数初始练习
1.整理函数相关知识点 2.写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者. def func(lst): lst = lst[1::2] return l ...
- 09-Python之路---函数进阶
Python之路---函数进阶️ 程序员三大美德: 懒惰 因为一直致力于减少工作的总工作量. 缺乏耐性 因为一旦让你去做本该计算机完成的事,你将会怒不可遏. 傲慢 因为被荣誉感冲晕头的你会把程序写得让 ...
随机推荐
- Linux更新时,出现无法更新锁
1.查看软件中心是否有更新 2.重启 3.rm/var/lib/dpkg/lock 4.sudo apt-get update 5.sudo dpkg --configure -a
- beego 初体验 - 参数与传值
beego 支持 restful 风格的 url 传值分为路由传值和表单传值,表单传值可以绑定实体对象 1行 :id/:date 就是路由传值 2.3行是表单传值的路由配置 后台如何接收? 这是con ...
- dubbo框架整合常见问题
逆向工程常见问题总结 tomcat7插件启动项目卡在:log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for ...
- js BOM浏览器对象模型
BOM即Browser Object Model,浏览器对象模型,表示浏览器窗口,所有js全局对象.函数以及变量均是window 对象的成员. 对于不同的浏览器,表示宽度和高度的方法不同: 对于IE9 ...
- Docker Swarm 常用命令
# 管理配置文件 docker config # 查看已创建配置文件 - docker config ls # 将已有配置文件添加到docker配置文件中 - dock ...
- 【Python65--tkinter:button】
一.需求:在Label页面增加一个按钮,点击此按钮,页面内容进行变化 思路: 1.上面放一个Label,下面放一个Button 2.采用frame框架 from tkinter import * #定 ...
- Arch Linux安装后的一些初始设置简介
配置有线网络. 没网络的时候,可以直接设定ip应急,后面 netctl 才是正规设置: # ip addr add 192.168.0.100/24 dev enp0s4# ip link set d ...
- FASM学习中的一些表格
Size operator Registers Data directives Conditions(jmp助记符)
- centos6.5下安装Nginx
链接: https://www.jb51.net/article/118595.htm
- server time zone
问题原因 由于使用的Mysql数据库驱动版本太高,存在数据库和系统时区差异,所以出问题. 问题解决 Spring Boot配置文件中在url: jdbc:mysql://127.0.0.1:3306/ ...