Pyhton基础学习系列14——函数

发布时间:2024年01月07日


提示:以下是本篇文章正文内容,下面案例可供参考

一、函数的定义

  1. 封装功能上相对独立而且会被重复使用的代码,可以减少重复代码的使用。
  2. 就类似于像print就是一个具有输出功能的函数,我们只需调用print就可以调用输出的功能。
  3. 使用函数是编写高效、可维护代码的关键。通过合理地使用函数,可以提高代码的质量,并更轻松地应对复杂的编程任务。

二、函数的分类

  • 不同的角度看可以有不同的分类,这里我主要把函数从使用者的角度分为三类,一个是系统函数,一个是标准库和第三方库函数,最后一个是自定义函数。

1.系统函数

  • 也就是内置函数,可以直接调用系统自带的叫做系统函数,例如print、len、max等等。
    在这里插入图片描述

2.标准库函数和第三方库函数

  • 标准库是指编程语言官方提供的、默认随编程语言安装的库。Python标准库包含了大量的模块,例如os、math、random等,它们提供了各种功能,如文件操作、数学运算、随机数生成等。
  • 第三方库是由独立的开发者或组织开发的库,不随编程语言默认安装。这些库扩展了编程语言的功能,提供了各种额外的模块和工具,用于特定领域的任务。在Python中,像NumPy、Pandas、Matplotlib等都是流行的第三方库,用于数据处理、科学计算、数据可视化等领域。
  • 总的来说,标准库提供了编程语言基本的核心功能和工具,而第三方库则扩展了语言的能力,满足了更广泛、更专业的需求。在实际编程中,通常会同时使用标准库和第三方库来完成任务。与系统函数相同的,他们也是无需自己编写程序,只用调用里面的函数即可。

3.自定义函数

  • 需要自己定义的函数叫做自定义函数,简单说就是系统函数、标准库、第三方库都没法直接实现的功能,需要自己编写程序实现某个功能定义的函数就叫做自定义函数。

三、函数的使用

1.基本语法

  • def function_name(parameters): 后面跟函数体也就是执行特殊功能的代码,最后返回想要的值。
  • function_name是函数的名称,用于调用函数时标识它。
  • parameters是传递给函数的参数,可以是零个或多个。
  • 最后要写一个return,用于将结果传递给调用函数的地方,如果不写就会是空值。
# def和return是固定写法
# function_name和parameters可以自己定义
def function_name(parameters):
  # 函数体
  # 执行特定任务的代码
  return result  # 可选的返回值

2.函数使用案例和说明文档

1.函数的说明文档

  • 是对一个函数的功能进行说明的文档,用三个双引号括起来。
  • 使用方法:只需要在函数体里面打上三个双引号然后回车就可以,会自动生成以下格式。
  • 作用:后面调用函数时把鼠标放在函数上面会显示你的说明文档,可以清楚的显示出这个函数应该传入什么类型参数,然后有什么功能,返回一个什么类型的数据
  • 不写也不会有问题。
def function_name(parameters):
    """
    
    :param parameters: 
    :return: 
    """
    return  

# 简单说明一下里面应该如何填写
def function_name(parameters):
    """
    这里说明函数的功能
    :param parameters:  接受参数的类型
    :return:   返回参数的类型
    """
    return

2.输入两个正整数,计算它们的最大公约数和最小公倍数

# gcd - greatest common divisor 最大公约数
# lcm - least common multiplier 最小公倍数
# 自定义gcd函数
def gcd(x, y):
    """
    计算最大公约数
    :param x: 第一个整数
    :param y: 第二个整数
    :return: 返回最大公约数
    """
    while x % y != 0:
        x, y = y, x % y
    return y

# 自定义lcm函数
def lcm(x, y):
    """
    计算最小公倍数
    :param x: 第一个整数
    :param y: 第二个整数
    :return: 返回最小公倍数
    """
    return x * y // gcd(x, y)

n1, n2 = map(int, input('输入两个正整数: ').split(' '))
print(f'最大公约数: {gcd(n1, n2)}')
print(f'最小公倍数: {lcm(n1, n2)}')
# 输入两个正整数: 15 18
# 最大公约数: 3
# 最小公倍数: 90
  • 以上这个例子只是为了我们更好的理解函数的应用,实际上我们完全可以用python自带的系统函数去解决。
from math import gcd, lcm
n1, n2 = map(int, input('输入两个正整数: ').split(' '))
print(f'最大公约数: {gcd(n1, n2)}')
print(f'最小公倍数: {lcm(n1, n2)}')
# 输入两个正整数: 15 18
# 最大公约数: 3
# 最小公倍数: 90

3.from和import的区别

  • import:用于导入整个模块,让整个模块的内容可用于当前文件。(一个py文件就是一个模块,每一个模块在python中是被看作一个独立的文件)。
  • 使用方法:import 模块名,可以使用模块中的函数和变量,但需要通过模块. 的方式来访问。
import random
list1 = [32, 43, 36, 33, 74, 88, 2, 42, 93, 20]
# random.shuffle是Python标准库中random模块提供的一个函数,用于将一个可变序列(比如列表)中的元素随机排列,从而实现打乱序列的效果。
random.shuffle(list1)
print(list1)
# [42, 74, 36, 43, 20, 32, 88, 33, 2, 93]
  • from:用于从模块中导入特定的部分(函数、类、变量等),使其在当前文件中可直接访问,无需通过模块名限定。
  • 使用方法:from 模块名 import 函数名,可以直接从模块中导入函数,可以直接使用,无需添加模块. 前缀
from random import shuffle
list1 = [32, 43, 36, 33, 74, 88, 2, 42, 93, 20]
shuffle(list1)
print(list1)
# [93, 36, 42, 32, 88, 74, 20, 43, 33, 2]
  • 二者区别在于import导入整个模块,而 from则只导入指定的内容。选择使用哪种方式取决于你的需求和偏好。当你只需要模块中的少量内容时,使用from可以让代码更清晰,避免频繁使用模块名前缀。然而,如果可能存在命名冲突或者想要整个模块的功能,使用 import 可能更合适。
  • import使用时需要模块. 前缀;from则不需要。
  • 这里提一个点,我们自己写的py文件也是可以导入的。

4.return和print的使用

  • return:用于在函数中返回数值或对象,并结束函数的执行,只能在函数中使用
  • 适用于需要将计算结果传递给调用者的情况,或在函数内部结束执行。
  • print: 用于将信息输出到控制台(标准输出),它通常用于调试和查看程序执行过程中的中间结果,但不会返回值给调用者。
  • 主要用于调试和展示中间过程,不适合作为函数的主要输出方式。
  • 一个好的函数一定使用return去返回程序结果的,有些时候可能用print也能实现效果,但是它无法让调用者使用返回值,总的来说一个用于返回值一个用来打印结果,要根据适当的需求去处理函数的输出。

四、函数的参数

1.形参和实参的区别

  • 形参(Parameters)在函数定义中,形参是指函数声明中的变量,用于接收函数调用时传递进来的值。形参相当于函数内部的变量,用来代表函数被调用时传递进来的数据。
  • 就类似于下面函数中的a和b,这两个变量用来接受调用函数时传入的参数。
def add(a, b):
  return a + b
  • 实参(Arguments)在函数调用时,实参是指传递给函数的具体数值或变量。实参是实际传递给函数的值,它们可以是变量、常量、表达式等。在调用函数时,实参会赋值给函数定义中对应的形参。
  • 在调用上面那个例子的函数时写入的3和5就是实参,它们会被传入到函数的形参当中,然后执行程序返回结果。
result = add(3, 5)
  • 总的来说,形参是函数定义时声明的参数名称,用于接收传递给函数的值;而实参是在函数调用时具体传递给函数的值或变量。函数调用时先将实参赋值给函数中的形参,就相当于做了一个形参=实参的操作,以便后续能让函数处理调用者传入的数据。

2.位置参数和关键字参数

1.位置参数

  • 位置参数(Positional Arguments)在调用函数时让形参和实参逐一对应。(参数的传递是按照位置的顺序来匹配的)
  • 在函数调用时,实参的顺序必须与函数定义中参数的顺序一致。
def func1(x, y, z):
    print('x:{}, y:{}, z:{}'.format(x, y, z))
        
func1(10, 20, 30)
# x:10, y:20, z:30
func1(20, 10, 30)
# x:20, y:10, z:30

2.关键字参数

  • 关键字参数(Keyword Arguments)实参和形参通过关键字(形参名)对应
  • 在函数调用中,可以通过指定参数名来传递参数(参数名=值的形式来传递参数)而不必依赖参数的位置,这就是关键字参数。
def func1(x, y, z):
    print('x:{}, y:{}, z:{}'.format(x, y, z))

func1(x=10, y=20, z=30)
# x:10, y:20, z:30
func1(z=10, x=20, y=30)
# x:20, y:30, z:10

3.位置参数和关键字参数混用

  • 如果要同时使用位置参数和关键字参数,位置参数必须在前,关键字参数必须在后,不然会报错。
  • 关键字参数不受位置顺序影响,但不能给位置参数赋值以后再用关键字赋值。
def func1(x, y, z):
    print('x:{}, y:{}, z:{}'.format(x, y, z))

func1(10, 20, z=30)
# x:10, y:20, z:30

# func1(10, 30, y=20)  # 不能这样写,y会被二次赋值而z得不到传参
# TypeError: func1() got multiple values for argument 'y'

# 使用关键字参数时不受位置顺序影响影响
func1(10, z=30, y=20)
# x:10, y:20, z:30

3.参数默认值

  • 是指在调用函数时,如果没有为某个参数提供值,那么该参数将使用预先定义的默认值。这可以使函数在不同情况下更灵活地使用,而无需每次都提供所有参数的值。
  • 定义函数的时候可以给形参写成参数名=数据的形式,相当于定义形参时直接赋值。
  • 调用函数时有默认值的参数可以不赋值
  • 如果调用函数时给有默认值的形参传值,新的实参会覆盖掉原来形参的默认值
def func2(x, y=20, z=10):
    print(f'x:{x},y:{y}')
    print(x + y + z)

# 调用函数时有默认值的参数可以不赋值
func2(20)
# x:20,y:20
# 50

# 如果调用函数时给有默认值的形参传值,新的实参会覆盖掉原来形参的默认值
func2(20, 10, 30)
# x:20,y:10
# 60

4.不定长参数(不确定函数参数个数时使用)

1.可变位置参数

  • 在函数定义时,可以使用星号*来表示可变位置参数,它将接收任意数量的位置参数,并将它们作为一个元组(tuple)传递给函数。
  • 元组中的元素就是对应的实参
  • 一般就在函数里加*args,然后它会接收传递给函数的所有位置参数,里面的args可以换个名字,重点是星号。
def func1(*args):
    print(args)

func1(10)
# (10,)

def func2(*args):
    sum1 = 0
    for num in args:
        sum1 += num
    print(sum1)

func2(10, 20, 64, 50)
# 144

2.可变关键字参数

  • 使用两个星号**来表示可变关键字参数,它将接收任意数量的关键字参数,并将它们作为一个字典(dictionary),传递给函数。
  • 通过关键字参数传参,关键字是key,数据是value
  • 一般就在函数里加**kwargs,然后它会接收传递给函数的所有关键字参数,里面的kwargs也可以换个名字,重点也是星号。
def func1(**kwargs):
    print(kwargs)

func1(a=20,b=30,c=40)
# {'a': 20, 'b': 30, 'c': 40}

def func2(**kwargs):
    for key in kwargs:
        print(kwargs[key])

func2(name='是靖不是静',age=22)
# 是靖不是静
# 22

3.可变参数的混合使用

  • 可以同时使用可变位置参数和可变关键字参数,使用要求和之前讲的位置参数和关键字参数是一样的,可变位置参数必须在前,可变关键字参数必须在后
  • 带*的和带**的参数可以同时出现,但是带*必须在带**的前面
  • 带*的参数必须使用位置参数传参,带**的参数必须使用关键字参数传参
def func1(*args, **kwargs):
    for i in args:
        print(i, end=" ")
    for key in kwargs:
        print(kwargs[key],end=" ")

func1(10, 20, 30, name='是靖不是静', age=22, sex='男')
# 10 20 30 是靖不是静 22 男 

五、匿名函数

  • 本质:匿名函数就是函数。匿名函数就是通过一条语句来实现函数的功能,关键字lambda
  • 有点类似于三目运算符一行代码实现判断进行输出,但注意并不是所有的函数都能适合写成匿名函数
  • 语法:函数名 = lambda 形参 : 返回值
  • 在一些需要传递函数作为参数的场景中,可以直接使用匿名函数而不必事先定义一个具名函数,方法可以看下面讲高阶函数的时候会提到。
# 练习:使用匿名函数生成一个保存了50以内3的倍数的列表。
# 这个是用for循环实现
list1 = []
for i in range(0, 51):
    if i % 3 == 0:
        list1.append(i)
print(list1)
# [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48]

# 列表推导式
list2 = [i for i in range(0, 51) if i % 3 == 0]
print(list2)
# [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48]

# 匿名函数实现
new_list = lambda x, y: [i for i in range(0, x + 1) if i % y == 0]
print(new_list(50, 3))
# [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48]

六、递归函数

  • 指在函数定义中调用函数本身的一种方法。(自己调自己)
  • 循环能做的递归都能做。(能用循环解决的就不要用递归)
# 计算N的阶乘
# 使用递归解决
def fac(n):
    if n == 1:
        return 1
    else:
    	# 在这个例子中,facn1函数计算阶乘。如果输入值n是0或1,则返回1。否则,它调用自己并将结果乘以n
        return n * fac(n - 1)
        # 依次类推
        # 3 * fac(2)  -> 3 * 2 * fac(1) -> 3 * 2 * 1
        # fac(2) = 2 * fac(1)
        # fac(1) = 1
# 这样函数自己调用自己的称为递归函数
print(fac(3))
# 6

七、高阶函数

1.使用方法

  • 高阶函数是指可以接受其他函数作为参数或者将函数作为结果返回的函数
  • 调用函数需要在函数名后面跟上圆括号,而把函数作为参数时只需要函数名即可
# 在函数内部在定义一个函数,用来检查一个任意数字是否是偶数
list1 = [25, 30, 10, 26, 29, 64, 23, 20, 5]
def fn(i):
    if i % 2:
        return False
    return True

def fn1(func, lst):
    # 对列表进行筛选
    # 返回新列表
    return [i for i in lst if fn(i)]

print(list1)
# [12, 35, 10, 21, 28, 64, 23, 20, 12]
print(fn1(fn, list1))
# 当fn函数为参数时,就是把fn的代码传入进去
# [12, 10, 28, 64, 20, 12]

2.Python中常见的高阶函数

1.filter - 过滤 - 留下你想要的,摘掉你不想要的 - built-in functions

  • filter(函数,可迭代对象)筛选可迭代对象中满足条件的元素,返回一个新的迭代器。
# 筛选奇数
list1 = [25, 30, 10, 26, 29, 64, 23, 20, 5]
temp1 = list(filter(lambda num: num % 2, list1))
print(temp1)
# [25, 29, 23, 5]

2.map(映射 - 把数据变成你想要的样子 - built-in functions)

  • map(函数,可迭代对象) -> 将可迭代对象按照指定的方式进行转换,返回一个新的迭代器。
  • map(函数,可迭代对象1,可迭代对象2)
# 用法一:将列表中每个元素的个位数组成一个新的列表
nums = [10, 23, 5, 89, 75, 102]
# 定义一个返回个位数的函数
def gewei(x):
    return x % 10
# 按照要求返回nums序列里面每一个元素的个位数
# 注意返回的是一个迭代器要转换列表
print(list(map(gewei, nums)))
# [0, 3, 5, 9, 5, 2]

# 用法二:将下面两个可迭代对象合并成一个字典
names = ['张三', '李四', '王五']
math = [66, 70, 90]
# 定义一个把可迭代对象1和可迭代对象2一一对应起来返回字典的函数
print(list(map(lambda x, y: {x: y}, names, math)))
# [{'张三': 66}, {'李四': 70}, {'王五': 90}]

3.reduce - 归约 - 对数据进行聚合(把多条数据变成一条数据)- functools module

  • reduce(函数,可迭代对象,初始值) 对序列中的元素进行操作并返回一个结果
  • 要使用 reduce 函数,首先需要导入 functools 模块,然后可以调用 functools.reduce() 来对序列进行归约操作
from functools import reduce
# 字符串连接
my_strings = ['Hello', ' ', 'World']
print(reduce(lambda x, y: x + y, my_strings))
# 输出:Hello World

my_numbers = [10, 4, 7, 15, 3]
# 求最大值
print(reduce(lambda x, y: x if x > y else y, my_numbers))
# 输出:15

# 累计求和
print(reduce(lambda x, y: x + y, my_numbers))
# 39

总结

高阶函数是一种强大的编程工具,可以灵活地处理函数,使代码更具表达力和通用性,Python中的函数是一段可重用的代码,用于执行特定任务,随着项目复杂性的增加,函数的使用变得更为重要。

文章来源:https://blog.csdn.net/qq_49771146/article/details/135371285
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。