python学习笔记08-函数

一、上堂回顾

1.默写题目

1.已知字符串str = "aBcedf",完成下面操作

​ a.获取字符串的长度

​ b.统计子字符串“a"在str中出现的次数

​ c.判断原字符串是否是以“abc”开头的

​ d.将其中的大写字母转换为小写

​ e.将其中的“def”替换为"hello"

​ f.获取"c"在原字符串中第一次出现的下标

str = "aBcedf"
l = len(str)
c = str.count("a")
result1 = str.startswith("abc")
newStr = str.lower()
str.replace("def","hello")
index1 = str.find("c")   #-1
index2 = str.index("c")   #报错

2.定义函数,求任意两个数的和

def myAdd(a,b):
  sum = a + b
  print(sum)
a = 10
b = 20
myAdd(a,b)
print(myAdd(a,b))  #None
​
​
def myAdd1(a,b):
  sum = a + b
  return sum
​
result = myAdd1(a,b)
print(result)
print(myAdd1(a,b))

2.知识点回顾

本质:是对特殊功能的封装

作用:简化代码,提高可维护性

定义:def

调用:函数名(实参)

参数:形参和实参,赋值的过程【传参】参数的传递:值传递和引用传递【不可变类型和可变类型】

注意:实参的数量和类型取决于形参

二、函数

1.函数概述

#需求:半径分别为r1 = 10,r2 =9.4,r3 = 22,求圆的面积
r1 = 10
r2 =9.4
r3 = 22
s1 = 3.14 * r1 ** 2
s2 = 3.14 * r2 ** 2
s3 = 3.14 * r3 ** 2
​
#使用函数优化
def area(radius):
  s = 3.14 * radius ** 2
  
area(r1)
area(r2)

在一个完整的项目中,某些功能会被反复使用,那么将该功能对应的代码封装成函数,当要再次使用这个功能的时候直接使用即可

本质:函数是对某个特殊功能的封装

优点:

​ a.简化代码结构,提高程序的模块性

​ b.提高代码的复用性

​ c.提高代码的可维护性【如果需求发生改变,则只需要更改函数内部】

2.函数使用

定义函数

语法:

​ def 函数名(参数1,参数2...):

​ 函数体

​ return 表达式或者常量或者变量

说明:

a.一个完整的函数由两个部分组成:函数的声明和函数的实现

b.def:definition,定义,函数是以def定义的

c.函数名:标识符,只需要遵循标识符的规则即可,尽量做到见名知意

d.(参数1,参数2...):()表示参数的开始和结束,其中参数1,参数2...被称为参数列表,本质上其实就是一个变量,参数列表也可以为空

e.函数体:需要被封装的特殊功能

f.return :返回,一般用于结束函数,并且将返回值携带给函数的调用者,不带任何数据的return其实相当于返回None

2.1简单的函数

简单的函数:无参无返回值的函数

代码演示:

#定义无参无返回值的函数
def myPrint():
    print("hello world")
​
#注意:函数定义好之后,不会自动执行,需要手动进行调用
"""
调用格式:函数名(实际参数)
说明:
a.出现在函数声明部分的参数被称为形式参数,简称形参,本质是一个变量    【形参 = 实参】
b.出现在函数调用部分的参数被称为实际参数,简称实参,本质上是一个数据
​
注意:
a.进行传参的时候,实参和形参需要保持匹配
b.如果形参为空,则调用函数的时候,()也不能省略
c.函数调用的本质:实参给形参赋值的过程
"""
​
myPrint()
myPrint()
myPrint()
myPrint()
myPrint()
​
​
#注意如果在同一个py文件中,出现同名的函数,则后出现覆盖掉先出现的
def myPrint():
    print("hello Python")
​
myPrint()

2.2函数的调用

代码演示:

#函数的调用
​
def show1():
    print("aaaaa")
    show2()
​
def show2():
    print("bbbbbb")
    show3()
​
def show3():
    print("ccccc")
​
show1()
#show2()
#show3()
​
#函数入栈

2.3函数的参数

函数的调用:实参给形参赋值的过程,被称为传参

代码演示:

#定义一个有参的函数
def myFunc(str,age):
    print(str,age)   #str = s1  age = a1
​
s1 = "abc"
a1 = 10
myFunc(s1,a1)
​
#注意:形参的数据类型取决于:实参的类型,具体的需求
​
def myFunc1(str,age,hobby):
    print(str,age,hobby)
    age += 1
​
​
#注意:实参和形参进行严格的匹配【类型,数量】
myFunc1("abc",10)

2.4参数的传递

1>值传递:传递的是不可变的数据类型,比如number,string,tuple

2>引用传递:传递的是可变的数据类型,比如list,dict,set

代码演示:

#值传递
def fun1(a):
​
    print(id(a))
    a = 10
    print(id(a))
​
temp = 20
print(id(temp))
​
#a = temp
fun1(temp)
​
print(temp)
​
#a的值发生改变,对temp的值没有影响
​
#引用传递
def fun2(c):
    c[1] = 100
    print(c)
​
d = [10,20,30,40]
fun2(d)
​
print("d = ",d)
​
#变量中存储的是地址

三、函数的基本使用【掌握】

1.参数的类型

1.1必需参数

调用函数的时候,必须以正确的顺序传参,传参的时候参数的数量和类型必须保持完全一致

代码演示:

#必需参数
#无参的函数
def test1():
    pass
​
#有参的函数
def  test2(a):
    pass
​
def test3(a,b,c):
    pass
​
#调用
test1()
test2(10)
test3(10,20,30)

1.2关键字参数

print(10,20,end=" ")

使用关键字参数允许函数调用的时候 实参的顺序和形参的顺序可以不一致,可以根据关键字进行自动的匹配

代码演示:

#关键字参数
def fun1(name,age):
    age += 1
    print(name,age)
​
#正常调用函数
fun1("lisi",10)
​
#使用关键字参数调用函数
fun1(name="zhangsan",age=20)
#fun1(30,name="jack")
fun1("lisi",age=30)
​
#注意;关键字参数只有一个的情况下,只能出现在参数列表的最后面
#fun1(name="lisi",30)  #SyntaxError: positional argument follows keyword argument
​
def fun2(a,b,c):
    print(a,b,c)
​
fun2(10,c=30,b=20)
​
#总结:
# 关键字参数出现在实参中
# 关键字参数要么出现在参数列表的末尾【一个或者多个】,要么全部是关键字参数
# 关键字参数的出现:形参可以不用保持一定的顺序
# 应用场景:Python内置的功能   print()

1.3默认参数

调用函数的时候,如果没有传递参数,则使用默认参数的默认值

注意:默认参数主要操作的是形参

代码演示:

#默认参数【default】
​
#1.默认参数如果不传参,则使用默认值,如果传参,相当于给形参重新赋值
def fun1(name,age=18):
    print(name,age)
​
fun1("lisi",20)
​
"""
age = 18
age = 20
"""
fun1("jack")
​
#2,在使用默认参数的同时,也可以使用关键字参数
fun1(name="abc",age=15)
fun1(name="hello")
​
#3.默认参数只能出现在参数列表的最后面,和关键字参数是类似的
def fun2(num1=10,num2=20):  #SyntaxError: non-default argument follows default argument
    print(num1,num2)
fun2()
fun2(11)

1.4不定长参数【可变参数】

可以处理比声明的时候更多的参数 * **

代码演示:

#不定长参数
#1.*
#注意1:*被当做tuple处理,形参的变量名其实就相当于一个元组的引用
#注意2:传参的时候,实参可以根据需求传任意数量和任意类型的数据
def fun1(*num):
    print(num)
    print(type(num))
​
fun1(10)
fun1(10,20,30,40)
fun1(38,45,True,"abc")
​
#注意3:不定长参数只能出现在参数列表的最后面,而且只能出现一个
def fun2(num1,num2,*num3):
    for num in num3:
        print(num)
​
fun2(10,20,30,50,54,5)
​
#注意4;可以在实参部分传一个元组,但是,元组被当做了一个整体,形成了二维元组
def fun3(*a):
    print(a)
​
fun3((3,53,5,4))
tuple1 = (3,53,5,4)
fun3(tuple1)
​
​
#2.**:被当做字典处理,变量名相当于字典名
def fun4(**args):
    print(args)
    print(type(args))
"""
{'x': 1, 'y': 2}
<class 'dict'>
"""
​
#fun4(10,20,30)
#注意:如果行参列表中出现了**,实参的传递必需以key=value的方式传参
fun4(x=1,y=2)
#类似于关键字参数,但是关键字参数必须和形参中的参数名保持一致,
#在**中,实参的参数名可以任意定义,相当于给字典中添加键值对
​
#3.混合使用
def fun5(*num1,**num):
    print(num,num1)
​
#分别被识别成了元组和字典
#fun5(23,4,35,35,name="zhangsan",age=10)
​
#注意:*和**混合使用的时候,**必须出现在形参列表的最后面
#fun5(name="zhangsan",age=10,23,4,35,35)

2.函数的返回值

return的使用

作用:a.结束函数 b.将一个函数运算的结果返回

注意:函数的返回值在函数中不是必须存在的,具体的需求

代码演示:

#return的使用
#1.返回一个数据  格式:return 数据
#需求:求任意两个数的和
def myAdd(num1,num2):
    total = num1 + num2
    return total
    #print("hello")     #注意1:return表示结束函数,无法执行return语句之后的其他语句
​
#注意2;函数的返回值谁调用,返回给谁【返回给调用者】
result = myAdd(10,20)
print(result)
print(myAdd(1,2))
def test():
    num = 10
print(test())
​
#2.返回多个数据,格式:return 数据1,数据2.。。。
#注意:多个数据被返回之后,当做元组进行处理
def test1(a,b,c):
    return a,b,c
print(test1("abc",10,True))   #('abc', 10, True)
​
#3.在分支语句中使用return
#注意:每个分支下的return语句不是必需的,如果每个分支都有return,返回的数据类型可以不一致
#需求;输入两个数,。比较两个数的大小,输出较大的一个
def compare(a,b):
    if a > b:
        return a
    elif a < b:
        return b
    else:
        return True
​
print(compare(10,20))
​
#4.return后面没有任何数据:只有一个作用,结束函数,返回值相当于是None
def test2(a,b):
    if a > b:
        return
​
print(test2(12,45))
​
#break和return的区别
def test3():
    for i in range(5):
        print(i)
        if i == 3:
            #break   #表示结束循环
            return  #表示结束函数
    print("over")
​
test3()

总结:

自定义函数,需要关注的问题

a.是否需要设置参数【如果有未知项参与运算】

b.是否需要设置返回值【函数运算的结果是不是需要在函数外部使用】

c.但凡涉及到功能,尽量封装函数

函数练习

代码演示:

"""
2.已知字符串 a = "aAsmr3idd4bgs7Dlsf9eAF",要求如下
    a.请将a字符串的大写改为小写,小写改为大写
    b.请将a字符串的数字取出,并输出成一个新的字符串
    c.请统计a字符串出现的每个字母的出现次数(忽略大小写,a与A是同一个字母),并输出成一个字典。 例 {'a':4,'b':2}
    d.输出a字符串出现频率最高的字母
    e.请判断 'boy'里出现的每一个字母,是否都出现在a字符串里。如果出现,则输出True,否则,则输 出False
    3.输入一个字符串,压缩字符串如下aabbbccccd变成a2b3c4d1
"""
a = "aAsmr3idd4bgs7Dlsf9eAF"
def stringOperation1(s):
    newStr = s.swapcase()
    return  newStr
stringOperation1(a)
​
def stringOperation2(s):
    newStr = ""
    for ch in s:
        if ch.isdigit():
            newStr += ch
    return newStr
​
def stringOperation3(s):
    s = s.lower()
    dict1 = {}
    for ch in s:
        if ch not in dict1:
            dict1[ch] = 1
        else:
            dict1[ch] += 1
​
    return dict1
​
def stringOperation4(s):
    #第一步;使用stringOperation3获取到的字典,获取value的最大值
    dict2 = stringOperation3(s)
    print(dict2)
    max = 0
    for value in dict2.values():
        if value > max:
            max = value
    #第二步:将value的最大值和字典中的value进行比对,如果相等,则获取对应的key
    for key,value in dict2.items():
        if value == max:
            print(key)
​
stringOperation4(a)
​
​
def stringOperation5(s):
    """
    list1 = [1,2,3,4,5]
    set1 = set(list1)
    set1.update([4])
    print(set1)
    """
    #将字符串转换为集合
    set1 = set(s)
    print(set1)
    search = "boy"
    set1.update(search)
    return len(set(s)) == len(set1)
​
print(stringOperation5(a))
​
#3.输入一个字符串,压缩字符串如下aabbbccccd变成a2b3c4d1
def stringOperation6(s):
    dict2 = stringOperation3(s)
    newStr = ""
    for key,value in dict2.items():
        newStr += key
        newStr += str(value)
​
    return newStr
​
print(stringOperation6("aabbbccccd"))

3.匿名函数

本质:lambda表达式

特点:

​ a.lambda只是一个表达式,比def定义的函数简单

​ b.将匿名函数赋值给一个变量,然后使用变量调用函数

​ c.将有限的逻辑封装到lambda表达式中,一般用来实现比较 简单的需求

​ d.lambda拥有自己的命名空间,而且不能访问自有参数列表之外的变量

语法:lambda 参数列表:函数体

#匿名函数
#需求:求两个数的和
def total(num1,num2):
    return num1 + num2
print(total(10,20))

#注意:匿名函数本质是一个表达式,并没有名字,想要被调用,只能赋值给一个变量,然后使用这个变量调用函数【变量当做函数名使用】
result = lambda  num1,num2:num1 + num2
print(result(10,20))

#特殊情况
#匿名函数也可以使用关键字参数进行参数传递
g = lambda  x,y:x ** 2 + y ** 2
print(g(2,3))
print(g(x=2,y=3))

#匿名函数也可以使用默认参数
g = lambda  x = 0,y = 0:x ** 2 + y ** 2
print(g())
print(g(2,3))
print(g(2))
print(g(y=3)

4.空函数和主函数

4.1空函数

一个什么功能都没有实现的函数,借助于pass语句

代码演示:

#空函数
def test():
    pass
​
test()

4.2主函数【main函数】

每个程序的入口

代码演示:

#模块中使用
if __name__ == "__main__":
    test()

三、函数的特殊使用【掌握】

1.变量可以指向函数

代码演示:

#1.变量指向函数
#abs()
print(abs(-10))  #10
​
print(abs)   #<built-in function abs>
#a.abs(-10)是函数调用,abs是函数本身
​
#想要获得函数调用的结果,可以将结果赋值给一个变量
x = abs(-10)
print(x)  #10
y = abs
print(y)  #<built-in function abs>
#b.函数本身也可以赋值给一个变量【变量指向函数】
​
print(y(-10))
#c。如果一个变量指向了一个函数,则可以通过该变量调用函数【变量名就是函数名】

2.函数名就是变量名

代码演示:

#2.函数名就是一个变量名
#abs():可以将函数名abs看成一个变量,它指向一个可以计算绝对值的函数   【num = 10】
​
#对abs重新赋值
abs = 10
#print(abs(-10))
​
#注意:不管是系统内置的功能,还是自定义的函数,函数名都是一个变量,指向了一个指定的函数,所以变量名尽量不要和函数名重名
#list = 100
list1 = list((54,54,654))
print(list1)

3.函数作为参数使用

代码演示:

#3.函数可以作为参数使用
#变量可以指向函数,函数的参数可以接收变量,那么一个函数可以接收另外一个函数作为参数,这种函数称为高阶函数
​
def test(x,y,f):
    return  f(x) + f(y)
​
print(test(10,-20,abs))    #x = 10 y = -10 f = abs   f(-10)
​
#注意:函数作为参数使用的时候,也需要遵循传参的规则
def hello(a):
    print("hello world")
​
def show(f):
    #相当于调用的是hello函数
    f(10)
​
show(hello)

四、偏函数【了解】

代码演示:

import functools
​
#偏函数
#作用:通过设定参数的默认值,可以减低函数的调用难度,而偏函数也可以做到这一点
#概念:对函数形式参数做一些控制的函数被称为偏函数
#注意:偏函数一般不需要自己定义,直接使用
​
#int(x) :将x转换为整型,当x为字符串时,默认按照十进制输出
#有一个默认参数base,默认值是10
print(int("123"))   #123
#print(int("abc123"))
print(int("123",base=10))
​
print(int("123",base=8))  #83
​
print(int("110",base=2))   #6
​
#需求:如果需要大量输出二进制
print(int("11010",base=2))
print(int("101010",base=2))
print(int("101110",base=2))
​
"""
def int2(x,base=2):
    return  int(x,base)
print(int2("11010"))
print(int2("101010"))
print(int2("101110"))
"""
​
#要实现上面的需求,系统提供了功能:functools.partial(_)
#偏函数:对于一个现成的函数,想要更改函数参数的默认值,生成一个新的函数,。被生成的函数被称为偏函数
#参数1;函数名  参数2:默认参数
int2 = functools.partial(int,base=2)
print(int2("11010"))
print(int2("101010"))
print(int2("101110"))
​
print((int2("10100",base=10)))
print(int("10101",base=2))

五、闭包

如果在一个函数的内部定义了另外一个函数,外面的函数叫做外部函数,里面的函数叫做内部函数

在一个函数的内部定义了另外一个函数,并且外部函数的返回值是内部函数的引用,这样就构成了闭包

代码演示:

#外部函数
#1.
def outerFunc():
    #内部函数
    def innerFunc():
        print("hello")
    return  innerFunc
​
r = outerFunc()   #r = innerFunc
print(r)   #<function outerFunc.<locals>.innerFunc at 0x000001D0BEF26510>
r()
​
#2.
#outer是外部函数,a和b都是外部函数的临时变量
def outer(a):
    b = 10
    def inner():
        #在内部函数中,可以访问外部函数的临时变量
        print(a + b)
    return  inner
​
#print(a,b)  #NameError: name 'a' is not defined
#调用;r1中保存了外部函数的返回值,也就是inner的引用【变量】,
r1 = outer(4)   #r1= inner
#r1()相当于是调用了inner函数
r1()
​
#闭包的应用场景:在Python中,装饰器

六、列表生成式和生成器

1.列表生成式

List Comprehensions,是Python内置的用来生成列表的生成式

range():

代码演示:

r = range(1,11)
print(type(r))  #<class 'range'>
print(list(r))    #[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(list(range(1,20,3)))
​
#需求:生成一个列表,[1,4,9,16,25,36]
l = []
for x in range(1,7):
    l.append(x * x)
print(l)   #[1, 4, 9, 16, 25, 36]
​
#列表生成式
#格式:[生成的元素规律   for循环   判断条件]
​
#1
l1 = [x * x for x in range(1,7)]
print(l1)  #[1, 4, 9, 16, 25, 36]
​
#2.使用if判断[4,16,36,64,100]
l2 = [x * x for x in range(1,11) if x % 2 == 0]
print(l2)
​
#3.使用嵌套for循环,生成的列表被称为全排列
l3 = [m + n for m in "ABC" for n in "XYZ"]
print(l3)
"""
for m in "ABC":
    for n in "XYZ":
"""
​
#4。for循环可以同时使用两个或者多个变量
d = {"x":"a","y":"b","z":"c"}
for k,v in d.items():
    print(k,"=",v)
​
l4 = [k + "=" + v for k,v in d.items()]
print(l4)
​
#1.将一个列表中的所有的字符改为小写,生成 一个新的列表
l1 = ["Hello","ABc","fdhf","YU"]
​
newList = []
for element in l1:
    newList.append(element.lower())
​
newList1 = [element.lower() for element in l1]

2.生成器

generator

作用:为了解决当快速的生成一批数据,瞬间占用过大的内存

工作原理:生成较大数据的时候,将数据存储到生成器中,当需要数据的时候,去到生成器中获取

定义生成器有两种方式:

a.将列表生成式中的[]换成(),就是一个生成器

b.通过函数和yield【让步】生成

注意:生成器可以通过next()遍历其中的元素

代码演示:

#1.
l1 = [x for x in range(1,6)]   #列表生成式
l2 = (x for x in range(1,6))    #生成器
print(type(l1))  #<class 'list'>
print(type(l2))  #<class 'generator'>
​
#生成器可以使用for循环进行遍历
"""
for i in l2:
    print(i)
"""
​
#通过调用next()获取生成器中的元素
print(next(l2))
print(next(l2))
print(next(l2))
print(next(l2))
print(next(l2))
​
#使用next获取生成器中的元素,当所有的元素被获取完成之后,继续调用next,则会出现StopIteration错误【异常】
#print(next(l2))
​
"""
​
1
​
2
3
4
5
"""
​
print("~~~~~")
​
#2.
def test(n):
    for x in range(1,n + 1):
        yield x   #暂停
        print(x)
​
tt = test(5)
print(tt)  #<generator object test at 0x000001A36A4A9200>
​
#print(next(tt))
for i in tt:
    print(i)
"""
1
1
2
2
3
3
4
4
5
5
总结:每次执行到yield的时候,则暂停代码的执行,将yield后面的值返回,代码停止
下次遍历生成器的时候【for和next】,函数生成器中的代码接着原来暂停的位置继续向下执行
"""

猜你喜欢

转载自blog.csdn.net/weixin_42569562/article/details/81366159