python笔记-函数

1、函数

  • 1.1 定义
    1)函数,就是把 具有独立功能的代码块 组织为一个小模块,在需要的时候,调用
    2)通俗理解,将多行代码写在一块,起个名字,在需要多个代码的时候,可以直接使用名字代替
    3)函数的好处:减少代码的冗余(重复的代码不用多写),提高程序的编写和执行效率
  • 1.2 函数定义
    1)将多行代码放在一块,起名字的过程
    2)函数必须先定义后调用
    3)定义的语法
    def 函数名():
    函数中的代码
    1)使用关键字 def,
    2)函数名需要遵守标识符规则
    3)处于def缩进中的代码成为函数体(用于实现函数功能的代码)
    4)函数定义的时候,函数体中的代码不会执行,调用的时候才会去执行
    5)书写小技巧:第一步可以先不管函数,先把功能写出来;第二步给多行代码起名字;第三步选中多行代码,使用tab键进行缩进
  • 1.3 函数的调用
    1)使用多行代码的时候,成为函数调用,通过函数名称进行调用函数
    2)调用的语法
    函数名()
    1)函数调用时,会执行函数体中的代码
    2)函数嗲用的代码,要写在函数体外边
点击查看代码
#函数的定义
def say_hello():
    print('hello 1')
    print('hello 2')
    print('hello 3')

#函数的调用
say_hello()
  • 1.4 文档注释
    1.文档注释的本质,还是注释,只不过书写的位置和作用比较特殊
    2.书写位置,在函数名的下方使用,三对双引号进行的注释
    3.作用:告诉别人这个函数如何使用的
    4.查看,在调用的手,将光标放到函数名上,按Ctrl+q (windows系统下) ctrl+j(mac系统)
    5.光标选择函数名,ctrl+B 转到函数声明中查看(按住ctrl 梳篦左击 自动调到函数体上)
  • 1.5 函数的嵌套调用
    1.函数定义不会执行函数体中的代码
    2.函数调用会执行函数体中的代码
    3.函数体中的代码执行结束会回到函数被调用的地方继续向下执行
点击查看代码
def func1():
    print('hello world 1')
    print('func1')
    print('hello world 2')

def func2():
    print('hello world 3')
    func1()
    print('hello world 4')

print('hello world 5')
func2()
print('hello world 6')
  • 1.6 函数的基础
点击查看代码
#1.定义一个函数,my_sum,对两个数字进行求和计算
def my_sum():
    num1 = 20
    num2 = 10
    num = num1 + num2
    print(num)

my_sum()
  • 1.函数存在的问题,这个函数只能对10 和 20 进行求和,不能对任意的数据进行求和计算处理
  • 2.问题的解决,想要解决这个问题,可以使用函数参数来解决
  • 3.函数参数:在函数定义的时候,使用变量代替具体得数据值(进行占位),在函数调用的时候,传递具体得数据值
  • 4.好处:让函数更加通用,能够解决一类问题,而不是淡出的一个问题
  • 5.形参:就是函数定义时,小括号里的参数,是用来接收参数用的,在函数内部作为变量使用
  • 6.实参:函数调用的时候,小括号里的参数,是用来把数据传递到函数内部用的
  • 7.函数可以没有形参和实参
点击查看代码
#1.定义一个函数,my_sum,对两个数字进行求和计算


#num1 和 num2 是函数定义时候的参数,起到占位的作用,没有具体的数据值,称为形式参数,简称:形参
def my_sum(num1, num2):
    num = num1 + num2
    print(num)


#在调用的时候,括号中的恶数据会传递给形参,是具体的数据值,称为实际参数,简称:实参
my_sum(11,22)
my_sum(1,2)
#目前书写🉐 函数,在定义的时候如果有形参,那么在调用的时候,必须传递实参值,个数对应否则会报错

2、函数返回值

  • 1.函数的返回值,可以理解为是,函数整体执行的结果是什么
  • 2.什么时候需要返回值:函数中得到的数据,在后续代码执行中还需要使用,这个时候就应该将这个数据作为返回值返回,以供后续使用
  • 3.在函数中使用return 关键字可以结果返回(return只能在函数中使用)1)将数据值作为返回值2)番薯代码执行遇到return,会结束函数的执行
  • 4.返回值说明:
    def 函数名(): #返回值 None
    pass #代码中没有return
    def 函数名():
    return #return 后面没有数据,返回值 None
    def 函数名():
    return xxx #返回值就是xxx
点击查看代码
print()  ---->None
input()  ---->键盘数据内容
type()   ---->类型
len()    ---->数据的长度(元素的个数)
def my_sum(a,b):
    num = a+b
    #print(num) #代码中没有返回值,只有print,这个结果只能在函数中用一次,不能后续使用
    #我们想要将这个求和的结果,在后续的代码中使用,需要使用return 将求和结果进行返回
    return num  #结果返回到调用的方法
    print('我是return之后的代码,我会执行吗--->不会执行')

#1.函数中没有print 只有return,想要查看结果,需要在调用的时候使用print
print(my_sum(1,2))
#2.想要将函数的中返回的结果,在后续代码中使用,即需要将这个数据保存下来,需要使用变量来接收(保存)函数的返回值(执行结果)
result = my_sum(10,20) #将求和的结果保存到变量 result中,可以再后续代码中使用
print(f'使用:1,直接打印:{result}')
print('使用:2,对结果 + 10:',result + 10)

3、变量进阶(理解、知道)

  • 3.1变量的引用
  • 1.在定义变量的时候-数据值,Python解释器会在内存中开辟两块空间
  • 2.变量和数据都有自己的空间
  • 3.日常简单理解,将数据保存到变量的内存中,本质是 将数据的地址保存到变量对应的内存中
  • 4.变量中存储数据地址的行为,就是“引用”(变量引用了数据的地址,简单说就是变量中存储了数据),存储的地址称为,引用地址
  • 5.可以使用id(),来获取变量中的引用地址(即数据地址),如果两个变量id()获取的引用地址一样,即代表着,两个变量引用了同一个数据
  • 6.只有赋值运算符=,可以改变变量的引用(等号左边数据的引用)
点击查看代码
a = 1 #将数据1的引用存在a对应的内存中
print(id(a))  #140714401571960

b = a # 将变量a中的引用 保存到变量b
print(id(b))   #140714401571960

a = 10 #将数据10的引用存在a对应的内存中

print(f'a:{id(a)}')  #a:140714401572248

0print(f'b:{id(b)}')  #b:140714401571960

4、可变和不可变类型

  • 1.数据类型:int float bool str list tuple dict set
  • 2.数据所在的内存是否允许被修改,允许修改就是可变类型,不允许修改就是不可变类型(不适用=,变量引用的数据中的内容是否会变化,会变化是可变的,不会变化是不可变的)
  • 3.可变类型:列表 list 字典 dict 集合 set
  • 4.不可变类型: int float bool str tuple
点击查看代码
my_list = [1,2,3,4,5,6]
my_list1 = [1,2,3,4,5,6]
print(f'my_list: {id(my_list)},{id(my_list[1])}') #my_list: 2524119036480,140714401571992
print(f'my_list1: {id(my_list1)}') #my_list1: 2524119152896

my_list[1] = 10
print(f'my_list: {id(my_list)},{id(my_list[1])}') #my_list: 2524119036480,140714401572248

my_tuple = (1,2,[3,4]) #元组中存储的是1 的地址,2的地址,和 列表的地址
#元组中的数据不能改变,是指这三个地址不能改变
print(f'my_tuple: {id(my_tuple)},{id(my_tuple[-1])}') #my_tuple: 2524120929584,2524120712000
my_tuple[-1][0] = 10 #修改的是列表中下标为0 的位置的引用地址,列表的地址没变,元组中的内容没有变化
print(f'my_tuple: {id(my_tuple)},{id(my_tuple[-1])}') #my_tuple: 2524120929584,2524120712000

#面试第一题
def func1(list1):    #mlist1 = my_list,引用相同
    list1.append(10)
my_list = [1,2]
func1(my_list)
print(f'my_list:{my_list}')  #my_list:[1, 2, 10]
#面试第二题
def func2(list1):  #list1 = my_list
    list1[0] = 10 #修改的是列表中 下标为0 位置的数据,没有修改列表的引用
my_list = [1,2]
func2(my_list)
print(f'my_list:{my_list}') #my_list:[10, 2]
#面试第三题
def func3(list1):
    list1 = [2,1]  #list1的引用发生变化,但my_list的引用没有发生变化,因此my_list的数据没有改变
my_list = [1,2]
func3(my_list)
print(f'my_list:{my_list}')  #my_list:[1, 2]
#面试第四题
#对于列表来说,+=的本质的extend操作
def func4(list1):   #list1 = my_list 引用相同
    list1 += [1,2]  #list1.extend(1,2) 没有直接使用等号去改变形参的引用,形参的数据改动会影响实参的值
my_list = ['a','b']
func4(my_list)
print(f'my_list:{my_list}')  #my_list:['a', 'b', 1, 2]
  • 4.1 交换两个变量的值
  • 1.组包(pack):将多个数据值使用逗号连接的过程,组成元组
  • 2.拆包(unpack):将容器中的数据值使用多个变量分别保存的过程,注意:变量的个数和容器中数据的个数保持一致
  • 3.赋值运算符,都是先执行等号右边的代码,执行的结果,保存到等号左边的变量中
点击查看代码
#交换a,b变量的值
a = 10
b = 20
#方法1:常规方法,引入第三个变量
# c = a   #将变量a中的值保存起来
# a = b   #将变量b中的值给 a
# b = c   #将变量c(即最开始 a的值)中的值给 b
# print(f'a:{a}, b:{b}')

#方法2:不使用第三个变量,使用数学中的方法
# a = a + b  #a 的值 30
# b = a - b  #30 - 20 ====> 10
# a = a - b  #30 - 10 ====> 20
# print(f'a:{a}, b:{b}')

#方法3:重点掌握,python特有
a,b = b,a
print(f'a:{a}, b:{b}')
#组包
c = b,a
print(type(c))

#拆包
a,b = c
print(f'a:{a}, b:{b}')

x,y,z = [1,2,3]
print(f'x:{x}, y:{y}, z:{z}')

3、函数的参数类型

  • 位置参数
    • 要求实参顺序必须和形参顺序完全一致,由形参顺序决定实参顺序
    • 代码示例
点击查看代码
def sum_num(a,b):    #形式参数,行参
   return a+b

result = sum_num(10,65)  #实际赋值的参数,实参
print(result)
  • 缺省参数
    • 定义函数时,可以给某个参数指定一个默认值,具有默认值的参数就叫做缺省参数
    • 示例代码
点击查看代码
def power(x,n=2):
    return x**n

result = power(2)
print(result)
result1 = power(5,3)
print(result1)

a = int('16',8)
print(a)
#编写一个自我介绍的函数

def info(name,age=18,gender='女', interests='sport'):
    return '我叫 %s,今年%d岁,我是一个%s生,我的兴趣爱好是%s' %(name,age,gender,interests)

miya = info('miya') #默认参数都不写
jake = info('jake',24,'男')  #按顺序更新部分默认参数
tom = info('tom',20,interests='swiming') #不按顺序更新部分默认参数
print(miya)
print(jake)
print(tom)
- 可变参数 - 传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个 - 示例代码
点击查看代码
def total(*args):  #使用可变参数
    result = 0
    for i in args:
        result += i*i
    return result

result = total(4,2,3,4,77,7,33,9,10)
print(result)
result1 = total(1,2,3,4,5,6)
print(result1)

def f(**kwargs):  #可变参数,接收字典
    for key, value in kwargs.items():
        print(key,value)
d = {'name':'xiaomi','age':18,'titel':'test'}
f(**d)

4、变量的作用域

  • 局部变量 是在函数内部定义的变量,只能在函数内部使用
  • 全局变量 是在函数外部定义的变量,所有函数内部都可以使用这个变量
    • 不可变数据类型 的 全局变量在函数中更新,需要通过global进行声明
    • 可变数据类型 的全局变量在函数中更新,不需要通过global进行声明
  • 示例代码
点击查看代码
#全局变量和局部变量
num1 = 10    #不可变数据类型
list1 = [1,2,3,4,5]  #可变数据类型

def f1():
    global num1   #通过global声明该变量就是全局变量,在该函数中对该变量操作会影响全局变量的值
    num2= 20    #局部变量,只在f1()函数中生效
    num1 = 21   #此处的num1只是和全局变量同名,并未修改全局变量的值
    list1[2] = 8
    print('函数f1打印全局变量mun1 %d' % num1)
    print('函数f1打印局部变量num2 %d' % num2)
    print('函数f1打印局部变量list1',list1)


f1()
print('在函数外面打印全局变量num1%d' % num1)
print('在函数外面打印全局变量list1',list1)

5、匿名函数

  • lambda函数时一种快速定义单行的最小函数,可以用在任何需要函数的地方
  • 优点:让代码更加精简,不需要考虑命名的问题
  • 匿名函数与map映射函数结合示例
点击查看代码
#匿名函数和其他函数结合使用
a = [1,2,3,4,5,7,8,9]
# def f(x):
#     return x*2
result = map(lambda x:x**3,a)   #映射,将a列表中的每个元素按照前面lambda函数做操作
print(list(result))
  • 匿名函数与reduce累积函数结合示例
点击查看代码
from functools import reduce
result = reduce(lambda x,y:x*y,a)
print(result)
# 等同于以下操作
result = 1
for i in a:
    result *= i
print(result)
  • 匿名函数与filter过滤函数结合示例
点击查看代码
#filter 过滤函数,筛选出列表中模2为0 的数
result = filter(lambda x:x%2==0,a)
print(list(result))

#筛选出列表中不为0的数生成新的列表
list1 = [1,2,3,4,0,53,2,1,34,5,6,7,0,43,2,1,0,1,34,5,0]
result = list(filter(lambda x:x!=0,list1))
print(list(result))

--提高示例,将列表中的元素组成一个整数

点击查看代码
#将列表中的元素组成一个数字1234053213456704321013450
list1 = [1,2,3,4,0,53,2,1,34,5,6,7,0,43,2,1,0,1,34,5,0]
#传统的实现方案
result = 0
mul = 1
for i in list1[::-1]:
    result += i * mul
    mul = mul*10**len(str(i))
print(result)
#传统正序实现
result = 0
for i in list1:
    result = result * (10**len(str(i))) +i
print(result)
#通过匿名函数和reduce累积函数实现
result = reduce(lambda x,y:x*10**(len(str(y)))+y,list1)
print(result)
#字符串拼接实现
result_str = ""
for i in list1:
    result_str +=  str(i)
result = int(result_str)
print("结果:%d,类型是:%s" % (result,type(result)))
#列表推导式实现
result = int(''.join(str(num) for num in list1))
print(result)

6、内置函数

  • abs() 对传入的参数求绝对值
  • bool() 对传入的参数取布尔值,None,0,"",[],{},()这些参数传入bool后,返回False
  • all() 所有传入的参数为真,才为真
  • any() 任何一个传入的参数为真,就为真
  • ascii() 自动执行传入参数的_repr_方法(将对象转换为字符串)
  • bin() 接收一个十进制,转换为二进制
  • oct() 接收一个十进制,转换为八进制
  • hex() 接收一个十进制,转换为十六进制
  • bytes() 字符串转换成字节,第一个传入参数是要转换的字符串,第二个参数按照什么编码转换为字节
  • str() 字节转换成字符串,第一个传入参数是要转换的字节,第二个参数按照什么编码转换为字符串
  • chr(65) 数字转字母或字符,查看ASCII码表
  • ord('A') 字母转数字,查看ASCII码表
  • compile() 接收.py文件或字符串作为传入参数,将其编译成python字节码
  • eval() 执行python代码,并返回其执行结果
  • exec() 执行python代码(可以是编译过的,也可以是未编译的),没有返回结果(返回None)
  • dir() 接收对象作为参数,返回该对象的所有属性和方法
  • help() 接收对象作为参数,更详细地返回该对象的所有属性和方法
  • divmod(100,10) 返回一个元组(10,0),第一个元素是100/10的商,第二个元素是100/10的余数
  • enumerate() 接收序列化类型的数据,返回一个迭代器(对象)
  • isinstance(object,class) 判断对象是否是某个类别的实例
    -filter() 对可迭代对象中的每一个元素,将其作为实参传入函数(或lambda表达式),如果函数返回False,将该元素丢弃,如果函数返回True,将该元素添加到filter的返回列值中,注意filter返回的是一个filter对象,实际应用中往往需要用list或tuple将其转换为列表或元组类型
  • map() 对可迭代的每一个元素,将其作为实参传入函数,将每一次调用函数返回的结果都添加到map的返回值中
  • format() 字符串格式化
  • forzenset() 转换为不可变的集合
  • globals() 返回一个字典,包括所有的全局变量与它的值所组成的键值对
  • locals() 返回一个字典,包括所有的局部变量与它的值所组成的键值对
  • hash() 对传入参数取哈希值并返回
  • id() 返回内存地址,可用于查看两个变量是否指向相同一块内存地址
  • imput() 提示用户输入,返回用户输入的内容(不论输入什么,都转换成字符串类型)
  • issubclass(subclass,class) 查看这个类是否是另一个类的派生类,如果是返回True,否则返回False
  • len() 返回长度
  • max() 接收序列化类型数据,返回其中值最大的元素
  • min() 接收序列化类型数据,返回其中值最小的元素
  • memoryview() 查看内存地址
  • next()
  • iter()
  • object()
  • pow(x,y) 求次方,返回x**y的结果
  • pow(x,y,z) 返回x**y%z的结果
  • peoperty() 获取对象的所有属性
  • range() 获取随机数或随机字符eg.range(0,10)从0到10的随机数
  • repr() 执行传入对象的_repr_方法
  • reversed() 对序列化类型数据反向排序,返回一个新的对象。注意与对象的reverse方法区别,后者是就地改变对象
  • sorted() 对序列化类型数据正向排序,返回一个新的对象。注意与对象的sort方法区别,后者是就地改变对象
  • silce() 对序列化类型数据切片,返回一个新的对象
  • round() 返回四舍五入后的结果
  • int() 转换为整型
  • list() 转换为列表类型
  • set() 转换为集合类型
  • str() 转换为字符串类型
  • tuple() 转换为元组类型
  • type() 返回对象类型
  • staticmethod() 返回静态方法
  • super() 返回基类
  • vars() 返回当前模块中的所有变量
  • zip() 接收多个序列化类型的数据,对各序列化数据中的元素,按索引位置分类成一个个元组

7、递归函数

  • 一个函数调用自身成为递归调用
  • 一个会调用自身的函数成为递归函数
  • 递归过程有三个步骤
    • 步骤1:写出临界条件
    • 步骤2:找这一次和上一次的关系
    • 步骤3:假设当前函数已经能用,调用自身计算上一次结果,再求出本次结果当参数满足一个条件时,函数不再执行
  • 示例1:计算上台阶方法
点击查看代码
#n(10)阶楼梯,每次上1个台阶或每次上2个台阶,问一共有多少种走法
#假如3阶楼梯
# 1 1 1
# 1 2
# 2 1
#f(n+1) = f(n) +f(n-1)
#f(n) = f(n-1) + f(n-2)
#n=0 f(n)=0
#n=1 f(n)=1
#n=2 f(n)=2
#n=3 f(n)=3
def f(n):  #计算出n阶楼梯,一共有多少种走法
    if n ==0:
        return 0
    elif n ==1:
        return 1
    elif n ==2:
        return 2
    return f(n-1) + f(n-2)

print(f'当楼梯是 {5} 阶时,一共有 {f(5)} 中走法')

# for i in range(10):
#     print(f'当楼梯是 {i} 阶时,一共有 {f(i)} 中走法')

#通过循环实现
list1 = [0,1,2]
for i in range(3,11):
    list1.append(list1[i-1] + list1[i-2] )
    print('当楼梯是 %d 阶时,一共有 %d 中走法' % (i,list1[-1]))
print(list1)
  • 示例2:计算斐波那契数列
点击查看代码
def feibonacci(n):
    '''
    使用递归计算斐波那契数列的第 n 项(从 0 开始计数)
    :param n:非负整数
    :return:第N项的值
    '''
    if n < 0 :
        return ValueError("输入必须是非负整数")
    elif n <= 1:
        return n
    return feibonacci(n-1) + feibonacci(n-2)
print(feibonacci(-1))
for i  in range(0,20):
    print('当n为 %d 时,斐波那契数列的值为%d' %(i,feibonacci(i)))
posted @ 2025-12-11 14:52  jake瑞  阅读(15)  评论(0)    收藏  举报