热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python函数(全局变量,局部变量,作用域,递归函数,高阶函数,匿名函数)

1.1函数1.1.1什么是函数函数就是程序实现模块化的基本单元,一般实现某一功能的集合。函数名:就相当于是程序代码集合的名称参数:就是函数运算时需要参与运算的值被称作为参数函数体:

 

1.1函数

1.1.1什么是函数

函数就是程序实现模块化的基本单元,一般实现某一功能的集合。
函数名:就相当于是程序代码集合的名称
参数:就是函数运算时需要参与运算的值被称作为参数
函数体:程序的某个功能,进行一系列的逻辑运算
return 返回值:函数的返回值能表示函数的运行结果或运行状态。

1.1.2函数的作用

  1.  函数是组织好的,可重复使用的,用来实现单一,或者相关功能的代码。
  2.  函数能够提高应用的模块性,和代码的重复利用率

我们已近知道python提供了许多内置函数,比如print(),我们自已创建的函数称为内置函数

1.1.3定义函数的语法

def 函数名(参数):
    函数体
    return  返回值内容

1.1.4函数定义规则

  1. 函数代码以def关键词开头,后接定义函数的名称和圆括号,冒号():
  2. 函数内容以冒号":"开始,并且缩进
  3. 函数内容的第一行内容可选择性使用文档字符串---用来定义该函数的说明
  4. 函数的返回值: return  [返回值内容]  用于结束函数,返回一个值,表示程序执行的结果。
  5. 函数不带return 默认返回None   返回值可以是任何类型的数据(数字,字符串,函数,列表,元祖,字典等),也可以是一个表达式
  6. 函数参数:任何传入参数和自变量必须放在圆括号中间,圆括号之间用于定义参数。

1.1.5函数调用

定义函数语法

def printinfo():
    print("hello world")
    return

调用函数

printinfo()
#函数执行结果
hello world

查看函数返回值

print(printinfo())
#结果
hello world
None             #默认函数值返回类容

其他返回值示例

def printinfo():
    print("hello world")
    return  [111+222]
print(printinfo())

#结果
hello world
[333]        #返回值内容

1.1.5函数参数

注:形参和实参(定义函数时,圆括号(参数)中的所有参数都是形式参数也称为形参,调用函数中,圆括号(参数)中的参数称为实际参数,也叫实参)

1)必须参数::

2)关键字参数:

3)默认参数:

4)可变参数(*args,**kwargs):

 1.必须参数:

从字面理解:必须要传入参数

传入的参数:与定义的形参顺序一一对应

技术分享图片技术分享图片
def stuinfo(name,age):
    print(name,age)
    return

#在不传入参数
stuinfo()  #调用函数

#函数执行结果
TypeError: stuinfo() missing 2 required positional arguments: name and age
#报错,提示类型错误,该函数,缺少两个位置参数
不传入参数
技术分享图片技术分享图片
def stuinfo(name,age):
    print(name,age)
    return
stuinfo("zhangsan",18) 
#函数执行结果
zhangsan 18
传入参数

 2.关键字参数

技术分享图片技术分享图片
def stuinfo(name,age,hobby):
    print(name,age,hobby)
    return

#参数位置匹配,关键字参数,与形参的位置顺序无关,
stuinfo(age=19,name="lisi",hobby="run")  
#name=   age=  hobby=就是关键字参数

#函数执行结果
lisi 19 run
关键字参数

3.默认参数

默认参数必须指向不变的对象

当函数有多个参数,把变化大的参数反正前面,变化小的参数放在后面。变化小的参数就作为默认参数。

默认参数好处:降低调用函数的难度

技术分享图片技术分享图片
#默认参数,可以直接使用用,也可以修改默认参数值
def grade(name,age,city="BeiJing"):  #city="BeiJing"  就是默认参数
    print(name,age,city)
# grade("yangjian",age=18)
grade("lala",age=18,city="shanghai")

#grade函数执行结果
lala 18 shanghai
默认参数

4.可变参数

*args  **args

用途:在定义函数需要,每个定义函数功能的都可以继续优化,所以我们需要用动态参数

如果把参数写死了,后期继续修改完善的功能的,修改该函数功能则会相当麻烦

*args  结果类型是元祖,传递值是任意类型

def test(*args):
    print(args)
test(123456,[12,45,88],{"name":"qw","age":15}) #可以传递任意参数的类型
#函数执行结果
(123456, [12, 45, 88], {name: qw, age: 15})

**kwargs结果类型是字典,传递值是以key=value方式传入

def test1(**kwargs):
    print(kwargs)
test1(name="xiha",age="12")

#执行结果
{age: 12, name: xiha}

函数* 和 ** 解包

技术分享图片技术分享图片
#*
def test(*args):
    print(args)
test(*[1,2,3,4,5,6,7,8,9])  #*参数解包,把【元素】 循环出来,添加到元祖中
#结果
(1, 2, 3, 4, 5, 6, 7, 8, 9)
*
技术分享图片技术分享图片
def test1(**kwargs):
    print(kwargs)
test1(**{"hobby":456,"number":789}) #**参数解包,把key:value 循环出来,添加到字典中
#结果
{number: 789, hobby: 456}
**

函数参数组合

def f2(a, b, c=0,*args,**kwargs):
    print(a =, a, b =, b, c =, c, args,kwargs)
f2(12,b=12,c=89,aa="as",bb="xxx")
#结果
a = 12 b = 12 c = 89 () {bb: xxx, aa: as}

函数参数总结:

1.形参的位置顺序,必须与实参的顺序一一对应,缺一不行,多一不行

2.关键字参数,无须一一对应,缺一不行,多一不行

3.位置参数必须在关键字参数左边

4.默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误

1.2全局变量和局部变量

在子程序中定义的变量称为局部变量,只在子程序内部生效,

在程序一开始定义的变量称为全局变量

全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。

当全局变量与局部变量同名时:在定义局部变量的子程序内,局部变量起作用,在其他地方全局变量起作用

name = "xixi"   #全局变量
def change_name():
    name = "haha"  #局部变量只在函数局部作用域内生效
    print("我的名字",name)
    return
change_name()
print(name)

def me():
    global name #声明name是全局变量  global
    name = "yj"  #修改name全局变量的值
    print(name)
    return
me()

如果全局变量是可变的数据类型,函数可以对全局变量内部直接进行修改

eng = ["merry","jack","petter"]
def chang():
    eng.append("mali")
    print(eng)
    return
chang()

总结:

一般写程序变量的命名规则

###全局变量变量名大写

###局部变量变量名小写

  1. 函数优先读取局部变量,能读全局变量,无法对全局变量重新赋值操作,#全局变量是不可变的类型
  2. 全局变量是可变类型,函数可以对全局变量进行操作
  3. 函数中有global关键字,变量本质就是全局变量,可读取全局变量,也可操作全局变量

1.3函数之间嵌套

name = "YangJIan"  #最外层

def change_name(): #第二层
    name = "YangJIan2"

    def change_name2(): #第三层
        name = "YangJIan3"
        print("第3层打印", name)
        
    change_name2()  # 调用内层函数
    print("第2层打印", name)
change_name()  #先执行局部函数的打印,
print("最外层打印", name)

# 第3层打印 YangJIan3
# 第2层打印 YangJIan2
# 最外层打印 YangJIan

注:多层函数嵌套,子级函数,只在子级函数内部生效。父级函数能调用子级函数的功能

1.4递归函数

1.在函数内部,可以调用其他函数,如果一个函数在内部调用自身本身,这个函数就是递归函数。

2.在使用递归策越是,必须有一个明确的敌对结束条件,称为递归出口

函数调用的时候,每次调用时要做地址保存,参数传递等。

如果函数包含了对其自身函数的调用,该函数就是递归。如下

def foo(n):
    #实现阶乘
    if  n == 1:
        return n  # 当满种条件n==1才执行return 操作
    res = n*foo(n-1) #调用自已本身的函数的结果(再判断条件是否满足条件)给res ,
    return res
print(foo(5))
#120

 递归算法所所体现的重复一般有的要求:

1.每次调用在上次规模上都有有所减小:

2.每次递归调用都是有明确条件的。

3.相领两次的重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出(返回值结果))就作为后一次的输入;

4.在问题的规模得到满足条件时,而不再进行递归调用。

1.5函数式编程

面向过程编程:我们通过把大段代码拆成函数,通过一层一层的函数,可以把复杂的任务分解成简单的任务,这种一步一步的分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。

函数式编程:是使用一系列函数去解决问题,函数式编程就是根据编程的范式来的出想要的结果,只要是输入时确定的,输出就是确定的。

1.6高阶函数

能把函数作为参数传入,这样的函数就称为高阶函数。

回到顶部

1.6.1函数即变量

以python的内置函数print()为列,调用该函数一下代码

>>> print("hello world")
hello world

#只写print
>>> print
in function print>

#可见print("hello world")是函数调用,而print是函数本身

要获得函数调用执行的结果,我们把结果赋值给变量:

>>> aa = abs(-20)
>>> aa
20

如果把函数本身赋值给变量

>>> p = print
>>> p
in function print>

#函数本身可以赋值给变量,变量可以指向函数

我们通过变量来调用这个print函数,验证结果如下

>>> p("check")
check

总结:函数名也是变量,对于print()这个内置函数,完全可以把函数名print看成变量,它指向一个可以打印任何东西的函数

注:实际程序代码绝不能这么写,上面只是为了举例说明,要恢复print函数,请重启python的交互环境

回到顶部

1.6.2传入函数

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

函数的返回值是一个函数名,也是高阶函数。

例如:一个简单的高阶函数

def add(x,y,z):
    return abs(x)+abs(y)
aa = add(12,23,abs)   #函数执行的结果 赋值给 aa
print(aa) #查看aa的值
#35 

#注,abs()函数是求一个整数的绝对值

1.7匿名函数

什么是匿名函数:

在python中有一个匿名函数lambda,匿名函数就是指:无需定义标识符(函数名)的函数或子程序。

定义lambda表达式:

lambda  arguments:express    

#arguments 参数(可以有多个参数)
#express 表达式

#lambda返回值是一个函数的地址,也就是函数对象
aa = lambda  arguments:express  #把的到lambda函数地址,赋值给变量aa

查看这个lambda函数地址   ,用aa(argument)   查看这个函数的值

例1

技术分享图片技术分享图片
def pf(x=0):
    return x**2
print(pf(3))
普通函数定义,求数字平方
技术分享图片技术分享图片
aa = lambda x:x**2
print(aa(4))
#16
lambda函数,求数字平方

 总结:

1.lambda函数可以参数可以有多个,包含的表达式不能超过一个,不要试图向lambda函数中塞入太多东西,如果你需要做复杂的功能,应该定义一个普通函数,想定义什么就定义什么。

2.lambda函数用在需要封装特殊的,非重用代码上,避免令我们的代码充斥大量的单行函数。

map函数

map()函数,map映射  

map(func,iterable)

map()函数接受两个参数,一个是函数,一个可迭代的对象(iterable),map将传入的函数依次作用到序列的每个元素,并把结果作为新的 可迭代的对象 的结果返回

例:有个函数,f(x) = x+1 把得到的数字 加1    要把这个函数作用在一个[1,2,3,4,5,6]上

number = [1,2,3,4,5,6]
#1.用普通函数定义方法
def add_one(x):
    return x+1
def map_test(func,arrey):
    res = []
    for i in arrey:
        i = func(i)
        res.append(i)
    return res
print(map_test(add_one,number))
#[2, 3, 4, 5, 6, 7]


#2.用lambda函数定义的得到结果,借助1定义的map_test函数
print(map_test(lambda x:x+1,number))
#[2, 3, 4, 5, 6, 7]

#3.用map()本身函数去定义
print(list(map(lambda x:x+1 ,number)))
#[2, 3, 4, 5, 6, 7]

#注:map()得出的结果是一个iterator ,需要用list()函数让它个整个序列都计算出来返回一个list

我们可能会想,写一个循环,也可以计算出结果,但要实现多个功能,是不是也要写多个循环 例:得出每个列表中元素的平方或则n次方

map()作为高阶函数,事实上把运算规则抽象了,不但可以计算简单的 f(x) = x+1 ,也能计算更复杂的函数。

总结:map() 处理序列中的每个元素,得到的结果是一个 iterator ,需通过list(iteratro),该list元素个数,与原来位置一样

reduce函数

在python2可以直接用reduce()函数

在python3需要调用reduce模块

from functools import reduce
reduce(function, sequence, initial=None)  #该函数的默认用法

reduce函数,将function作用sequence序列的元素,每次携带一对(先前的结果以及下一序列的元素),连续的将现有的结果和下一个作用在获得的随后的结果上,最后得到我们的序列为一个最终结果的返回值

技术分享图片技术分享图片
number1 = [2,3,4,10]
#1.普通函数定义
def chengfa(x,y):
    return x*y  #返回得到两个数相乘的结果
def reduce_test(func,seq,init=None):
    if init is None:
        res = seq.pop(0)   #seq删除第一个元素,并获取删除这个元素 赋值给res
    else:
        res = init
    for i in seq:
        res = func(res,i)  #循环一次,执行func这个函数
    return res
print(reduce_test(chengfa,number1))
#240
print(reduce_test(chengfa,number1,10))
#2400

#如果给了init 初始值,就是从初始值 乘以列表的每个元素的的出结果

#2.lambda函数,借助reduce_test()函数定义
print(reduce_test(lambda x,y:x*y,number1,init=3))
#720

#3.使用reduce(),结合lambda()
print(reduce(lambda x,y:x*y, number1))
#240

得到列表所有元素,相乘的结果

number1 = [2,3,4,10]
#1.普通函数定义
def chengfa(x,y):
    return x*y  #返回得到两个数相乘的结果
def reduce_test(func,seq,init=None):
    if init is None:
        res = seq.pop(0)   #seq删除第一个元素,并获取删除这个元素 赋值给res
    else:
        res = init
    for i in seq:
        res = func(res,i)  #循环一次,执行func这个函数
    return res
print(reduce_test(chengfa,number1))
#240
print(reduce_test(chengfa,number1,10))
#2400

#如果给了init 初始值,就是从初始值 乘以列表的每个元素的的出结果

#2.lambda函数,借助reduce_test()函数定义
print(reduce_test(lambda x,y:x*y,number1,init=3))
#720

#3.使用reduce(),结合lambda()
from functools import reduce
print(reduce(lambda x,y:x*y, number1))
#240
得到列表所有元素,相乘的结果
技术分享图片技术分享图片
print(reduce(lambda x,y:x+y,range(1,101)))
得到1-100的和

filter函数

filter()函数用于过滤序列

和map()类似,filter()也接受一个函数和一个序列(可迭代的对象,也就是能被for循环),和map()不同的是,fillter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

例:

技术分享图片技术分享图片
aa = [A, ‘‘, B, None, C,   ]
#1.自定义函数测试
def not_empty(s):
    return  s and s.strip()
def filter_test(func,iter):
    res = []
    for i in iter:
        i = func(i)
        if i:
            res.append(i)
    return res
print(filter_test(not_empty,aa))

#[‘A‘, ‘B‘, ‘C‘]

#2.filter内置函数测试
print(list(filter(not_empty,aa)))
#[‘A‘, ‘B‘, ‘C‘]
把列表中空字符串,空元素,都去掉

filter()这个函数,关键在于正确实现一个筛选函数,

注:filter()函数返回的是一个iterator,内存地址,需要看内存地址的值, 用list()函数或得该地址的值 

sorted函数

sorted()函数也是一个高阶函数,它可以接收key

sorted排序,排序是比较元素的大小,如果是数字可以直接比较,如果是字符串或则两个dict(字典)?

sorted()传入的参数是可迭代的对象,返回值的对象是一个列表

例:

技术分享图片技术分享图片
aa = [11,-10,20,21,30,-40]
print(sorted(aa))
数字默认排序

接收一个key函数来实现自定义排序

例:根据绝对值大小来进行排序

技术分享图片技术分享图片
aa = [11,-10,20,21,30,-40]
print(sorted(aa,key=abs))
#[-10, 11, 20, 21, 30, -40]
根据绝对值排序

例:字符串排序

技术分享图片技术分享图片
print(sorted("hello"))
#[‘e‘, ‘h‘, ‘l‘, ‘l‘, ‘o‘]
print(sorted(["hello","ho","haha"]))
# [‘haha‘, ‘hello‘, ‘ho‘]
字符串排序

注:默认情况下,对字符串排序是按照ASCII编码表的大小进行比较的

最后总结:

python内置的几个高阶函数:map() ,reduce(),filter,sorted()

python函数(全局变量,局部变量,作用域,递归函数,高阶函数,匿名函数)


推荐阅读
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 本文介绍了django中视图函数的使用方法,包括如何接收Web请求并返回Web响应,以及如何处理GET请求和POST请求。同时还介绍了urls.py和views.py文件的配置方式。 ... [详细]
author-avatar
戴乐季206
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有