Python核心基础DAY4--Python函数和内置函数总结

前面相关文章:

Python核心基础DAY1--Python的基础变量类型之字符串和数字类型

Python核心基础DAY2--复合类型之序列类型、映射类型和集合类型

Python核心基础DAY3--Python表达式及常见语句


Python函数

函数是可以重复执行的语句块,可以重复调用,用于封装语句块,提高代码的重用性。

是面向过程编程的最小单位

函数的定义:使用def 语句定义一个函数

def function_name(parameters):
    # 函数体
    # 进行一些操作
    return result  # 可选的返回值
  1. def:用于声明一个函数,告诉 Python 这是一个函数的定义。
  2. function_name:函数名,一个有效的标识符,规则和变量名一致。
  3. parameters:形参,可以是0 ~ n 个,参数之间用逗号分隔。
  4. 函数体:定义函数执行的具体操作。
  5. return:指定函数的返回值,没有则返回None。

一、内置函数

Python提供了大量的可直接使用的内置函数,主要执行一些常见的操作:数据处理、类型转换、数学计算、输入输出等。

官方地址:内置函数 — Python 3.13.5 文档

all() -- 如果可迭代对象中的所有元素都为 True,返回 True,否则返回 False

print(all([True, True, False]))  # 输出: False
print(all([1, 2, 3]))           # 输出: True

sum() -- 返回可迭代对象中所有元素的总和

print(sum([1, 2, 3]))  # 输出: 6

sorted() -- 返回一个新列表,其中包含可迭代对象中的元素,按照升序排序

print(sorted([3, 1, 2]))  # 输出: [1, 2, 3]

reversed() -- 返回一个反向迭代器

print(list(reversed([1, 2, 3])))  # 输出: [3, 2, 1]

callable() -- 检查对象是否可以被调用(即是否是函数或方法)

print(callable(print))  # 输出: True
print(callable(123))    # 输出: False

zip() -- 将多个可迭代对象打包成一个元组,常用于并行遍历多个序列

names = ["Alice", "Bob"]
ages = [25, 30]
zipped = zip(names, ages)
print(list(zipped))  # 输出: [('Alice', 25), ('Bob', 30)]

eval() -- 将字符串作为有效的 Python 表达式来执行,并返回结果

x = 10
result = eval("x + 5")
print(result)  # 输出: 15

exec() -- 执行存储在字符串中的 Python 代码

code = 'for i in range(3): print(i)'
exec(code)
# 输出:
# 0
# 1
# 2

globals() locals() -- globals() 返回当前全局符号表(一个字典);locals() 返回当前局部符号表(也是字典)

x = 10
print(globals())  # 输出: 包含全局变量的信息
print(locals())   # 输出: 包含局部变量的信息

filter(function, iterable) -- 从可迭代对象中过滤出符合条件的元素

  1. 接受一个函数和一个可迭代对象
  2. 用接受的函数来筛选出可迭代对象中满足条件的元素
  3. 返回一个包含满足条件的元素的迭代器
numbers = [1, 2, 3, 4, 5]
filtered = filter(lambda x: x % 2 == 0, numbers)
print(list(filtered))  # 输出: [2, 4]
练习1
import math
def maxfn(data):
    # 数据类型:list tuple set
    assert isinstance(data, (list, tuple, set)),TypeError('数据类型错误')
    max = -math.inf # 负无穷
    for i in data:
        if not isinstance(i, (int, float)): # 判断数据类型
            raise TypeError('数据类型错误')
        if i > max:
            max = i
    return max
print(maxfn([11,22,32,41,15]))
print('-'*50)
print(maxfn([1,2,'nihao']))

练习2
import random
with open('./students.txt',mode='r',encoding='utf-8')as f:
          # 读取整个文件内容
          content = f.read()
          # 切割为列表
          students = content.splitlines()
          print(students)
          # 读取已经被选中的学生
          with open('./天选.txt',mode='r',encoding='utf-8')as f1:
                  stus = f1.read().splitlines()
          # 智能选择没有选中的学生
          vailstus = list(set(students).difference(set(stus)))
          # 随机一个学生的下标
          ind = random.randint(0,len(vailstus)-1)
          # 根据随机的下标获取学生
          student = vailstus[ind]
          # 抽中的学生需要写入新的文件:记录下来
          with open('./天选.txt','a',encoding='utf-8') as f2:
                  f2.write(vailstus[ind]+'\n')  

二、函数调用

函数调用时传递参数的方式有多种,包括位置传参、关键词传参、多个参数解包、参数默认值等。

位置传参 — 最常见的传参方式,参数按定义的顺序依次传入函数

def greet(name, age):
    print(f"Hello, {name}. You are {age} years old.")
greet("Alice", 30)  # 输出: Hello, Alice. You are 30 years old.

关键词传参 — 通过指定参数的名称来传值,无顺序限制,代码可读性较高

def greet(name, age):
    print(f"Hello, {name}. You are {age} years old.")
greet(age=30, name="Alice")  # 输出: Hello, Alice. You are 30 years old.

参数默认值

定义函数时可为某些参数指定默认值,如果不传参则使用默认值。默认值参数必须位于无默认值参数的后面。

def greet(name, age=25):
    print(f"Hello, {name}. You are {age} years old.")
greet("Alice")       # 输出: Hello, Alice. You are 25 years old.
greet("Bob", 30)     # 输出: Hello, Bob. You are 30 years old.

可变位置参数

使用 *args 可让函数接受任意数量的位置参数。*args 会将多余的位置参数收集成一个元组

def sum_numbers(*args):
    return sum(args)
print(sum_numbers(1, 2, 3))     # 输出: 6
print(sum_numbers(1, 2, 3, 4))  # 输出: 10

可变关键词参数

使用 **kwargs 可以让函数接受任意数量的关键词参数。**kwargs 会将多余的关键词参数收集成一个字典

def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")
print_info(name="Alice", age=30)
# 输出:
# name: Alice
# age: 30

多参数解包

Python 允许在调用函数时解包序列或字典,使其作为位置参数或关键词参数传递给函数。

解包位置参数 — 使用 * 解包

def greet(name, age):
    print(f"Hello, {name}. You are {age} years old.")
args = ["Alice", 30]
greet(*args)  # 输出: Hello, Alice. You are 30 years old.

解包关键词参数 — 使用 ** 解包 

def greet(name, age):
    print(f"Hello, {name}. You are {age} years old.")
kwargs = {"name": "Alice", "age": 30}
greet(**kwargs)  # 输出: Hello, Alice. You are 30 years old.

参数混合使用

***备注
可变参数位置参数关键词参数用在形参前面
参数解包位置参数解包,比如list、tuple关键词参数解包,比如dict用在实参前面

在函数调用时,可以混合使用位置参数和关键词参数,但位置参数必须放在关键词参数前面。 

def greet(name, age, city="Unknown"):
    print(f"Hello, {name}. You are {age} and live in {city}.")
greet("Alice", 30)  # Hello, Alice. You are 30 and live in Unknown.
greet("Bob", 25, city="New York")  # Hello, Bob. You are 25 and live in New York.

三、可变和不可变参数

在 Python 中,实参可以是可变类型或不可变类型。它们的区别主要体现在值传递引用传递的行为上。

不可变类型

  1. 不可变类型包括:int、float、str、tuple、frozensetint、float、str、tuple、frozensetint、float、str、tuple、frozenset 等。
  2. 传递方式是值传递: 传递给函数的是该对象的值,函数内部修改该值不会影响外部变量的值。
def modify(x):
    print('修改之前:', x, id(x))
    x = 10      # 修改了 x 的值,但不会影响外部变量
    print('修改之后:',x, id(x))
a = 5
modify(a)
print('原始数据:',a, id(a))
修改之前: 5 140722275297848
修改之后: 10 140722275298008
原始数据: 5 140722275297848

可变类型

  1. 可变类型包括:list、dict、setlist、dict、setlist、dict、set 等。这些类型的对象可以在原地修改。
  2. 传递方式是引用传递 :传递给函数的是对象的引用(即内存地址),在函数内部修改该参数的内容会直接影响外部变量。
def modify(lst):
    print('修改之前:', lst, id(lst))
    lst.append(4)  # 修改了 lst 对象的内容
    print('修改之后:',lst, id(lst))
a = [1, 2, 3]
modify(a)
print('外部原始数据:',a, id(a)) 
修改之前: [1, 2, 3] 2123053058816
修改之后: [1, 2, 3, 4] 2123053058816
外部原始数据: [1, 2, 3, 4] 2123053058816

四、匿名函数lambda

匿名函数是没有名字的函数,通常用于需要一个简短的、临时的函数场景,它可以有任意数量的参数,但只能包含一个表达式,并返回该表达式的结果。

基本语法:

lambda arguments: expression
# arguments:一个或多个输入参数,可以是位置参数或关键词参数。
# expression:一个单一的表达式,它的值将作为返回值返回。

匿名函数定义 

# 定义一个 lambda 函数,接收两个参数 a 和 b,返回它们的和
add = lambda a, b: a + b
print(add(3, 5))  # 输出: 8

使用场景

lambda 函数常常与高阶函数如 map()、filter() 和 sorted() 等一起使用。

处理列表

numbers = [1, 2, 3, 4, 5]
# 使用 map() 将每个数字平方
squared_numbers = list(map(lambda x: x ** 2, numbers))
print(squared_numbers)  # 输出: [1, 4, 9, 16, 25]

筛选列表 

numbers = [1, 2, 3, 4, 5, 6]
# 使用 filter() 筛选出偶数
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)  # 输出: [2, 4, 6]

实现排序 

# 按照字典的值排序
dict_list = [{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}, {"name": "Charlie", "age": 35}]
# 按照 age 排序
sorted_dict_list = sorted(dict_list, key=lambda x: x["age"])
print(sorted_dict_list)
# 输出: [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]

条件表达式

可以在 lambda 函数中使用条件表达式(if-else)来做一些简单的决策

# 判断是否为偶数
is_even = lambda x: "Even" if x % 2 == 0 else "Odd"
print(is_even(4))  # 输出: Even
print(is_even(7))  # 输出: Odd

匿名函数优点

  1. 结构简单lambda 函数通常用在需要一个短小函数的地方,而普通函数则更适合复杂的逻辑。
  2. 匿名性lambda 函数是没有名字的,它们通常只在一个地方使用,并且不需要被重复调用。
  3. 功能限制lambda 函数只能包含一个表达式,不可以包含多行语句,而普通函数可以包含多行代码、条件判断、循环等复杂逻辑。

五、高阶函数

高阶函数是指可以接受一个或多个函数作为参数,或者返回一个函数作为结果的函数。

map — map(function函数, iterable可迭代对象)

  1. 接受一个函数和一个可迭代对象
  2. 将接受的函数应用到可迭代对象的每个元素上
  3. 返回一个包含结果的迭代器
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
# squared现在包含[1, 4, 9, 16, 25]

filter函数 — filter(function, iterable)

  1. 接受一个函数和一个可迭代对象
  2. 用接受的函数来筛选出可迭代对象中满足条件的元素
  3. 返回一个包含满足条件的元素的迭代器
numbers = [1, 2, 3, 4, 5]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
# even_numbers现在包含[2, 4]

reduce函数 — reduce(function函数, iterable[, initializer]可迭代对象)

  1. reduce函数接受一个函数和一个可迭代对象
  2. 将接受的函数累积地应用到可迭代对象的元素上
  3. 可选的 initializerinitializerinitializer 参数可以作为累积的初始值
from functools import reduce
numbers = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
# product现在包含120 (1 * 2 * 3 * 4 * 5)

作为参数高阶函数可以接受其他函数作为参数,用于自定义行为。

def sort_custom_key(item):
    return item[1]
data = [('apple', 3), ('banana', 1), ('cherry', 2)]
sorted_data = sorted(data, key=sort_custom_key)
# sorted_data现在包含[('banana', 1), ('cherry', 2), ('apple', 3)]
fn_oper = {
    "add": lambda a, b: a + b,
    "sub": lambda a, b: a - b,
    "mul": lambda a, b: a * b,
    "div": lambda a, b: a / b if b != 0 else None,
}
def dowhat(a, b, fn):
    if not callable(fn):
        assert fn in fn_oper, "无效操作"
        fn = fn_oper[fn]
    return fn(a, b)
print(dowhat(100, 200, fn_oper["add"]))
print(dowhat(100, 200, "add"))
print(dowhat(100, 200, "add1"))

六、变量作用域

变量的作用域是指在程序中某个变量的有效范围,也就是在代码的哪个部分可以访问或修改该变量。作用域定义了变量的可见性和生命周期。

变量作用域遵循LEGB规则(Local, Enclosing, Global, Built-in),依次搜索变量的定义位置。

Local→局部作用域

  1. 指函数或方法内部定义的变量。
  2. 仅在函数内部有效,函数外部无法访问。
  3. 在函数调用时被创建,在函数调用后自动销毁。

Enclosing→嵌套作用域

  1. 指外层函数中的变量,在内层函数中可访问,但不可修改。
  2. 当一个函数嵌套在另一个函数内部时,外层函数的变量属于Enclosing作用域。
def outer():
    x = 20  # 外层函数变量
    def inner():
        print(x)  # 访问外层函数变量
    inner()

nonlocal:将局部作用域中变量声明为外部嵌套函数作用域中的变量 

#外部嵌套作用域
def func01():
    a = 10
    def func02():
        # 内部函数,如果修改外部嵌套变量,需要使用nonlocal语句声明
        nonlocal a
        a += 20
    func02()
    print(a)
func01()

Global→全局作用域

  1. 指模块级别定义的变量,整个模块都可以访问。
  2. 如果想在函数中修改全局变量,需要使用global关键字。
count = 0
def hello(name):
    global count  # 声明 count 是全局变量
    print('hello', name)
    count += 1
hello('小张')
hello('小李')
hello('小魏')
print('您共调用hello函数', count, '次')

Built-in→内建作用域

  1. 包含Python内建的函数、异常和常量,如print(), len(), int, Exception等。
  2. 这些变量可以在任何地方使用。
print(len([1, 2, 3]))  # 使用内建函数len

变量查找顺序 — 作用域遵循LEGB规则(Local, Enclosing, Global, Built-in):

x = "global"
def outer():
    x = "enclosing"
    def inner():
        x = "local"
        print(x)  # 输出局部变量 'local'
    inner()
outer()

如果不使用 global 关键字,函数内修改的会是局部变量,而不是全局变量。 

七、函数内存分配

  1. 将函数的代码存储到代码区,函数体中的代码不执行。
  2. 调用函数时,在内存中开辟空间(栈帧),存储函数内部定义的变量。
  3. 函数调用后,栈帧立即被释放。
def func(a, b):
  a = 20
  b[0] = 20
a = 10
b = [100]
func(a, b)
print(a) # 10
print(b) # [20]

八、递归函数

递归是指函数直接或间接调用自身的过程。递归通常用于解决分解成相似子问题的复杂问题。

递归函数通常由两个部分组成:

  1. 终止条件:用于确保递归能够停止,避免无限递归。
  2. 递归调用:函数在其内部调用自身,传递简化或减少的参数,以解决更小的子问题。

阶乘定义

  1.  n! = n * (n-1) * (n-2) * ... * 1
  2. 递归公式:n! = n * (n-1)!  ,终止条件:0! = 1
def factorial(n):
    # 终止条件:n为0或1时,返回1
    if n == 0 or n == 1:
        return 1
    # 递归调用:n * (n-1)!
    return n * factorial(n - 1)
# 测试
print(factorial(6))  # 输出 720

斐波那契数列

def fb(n):
    if n == 0 or n == 1:
        return n
    return fb(n - 1) + fb(n - 2)

九、总结 

Python中的语句是程序执行的最小单位,涵盖多种类型以实现不同功能。赋值语句用于给变量赋值;条件语句包括if-elif-else和Python 3.10后新增的match-case,前者根据条件执行不同代码块,后者适合多条件判断,支持多值匹配和嵌套if判断。循环语句有for循环和while循环,for循环用于遍历列表、元组等可迭代对象,while循环在条件为真时重复执行,且支持嵌套;range函数可生成整数序列辅助循环,循环中可通过break跳出整个循环、continue跳过当前循环,pass作为占位符不执行操作。字典遍历可通过键、值或键值对进行。异常处理语句包括try-except-finally捕获处理错误,raise主动抛出异常,assert用于断言检查,确保程序在错误发生时能合理响应。

函数是封装可重复执行语句块的工具,通过def定义,包含参数、函数体和可选返回值。Python提供丰富内置函数,如all、sum、sorted等,用于数据处理、类型转换等常见操作。函数调用方式多样,包括位置传参、关键词传参,支持参数默认值、可变位置参数(*args)和可变关键词参数(**kwargs),还可通过*和**解包序列或字典作为参数。参数传递中,不可变类型(如int、str)采用值传递,函数内修改不影响外部;可变类型(如list、dict)采用引用传递,修改会影响外部变量。

匿名函数lambda简洁高效,仅含一个表达式,常作为参数传给高阶函数如map、filter、sorted。高阶函数可接受或返回函数,map将函数应用于可迭代对象每个元素,filter筛选符合条件元素,reduce累积应用函数处理元素。变量作用域遵循LEGB规则,依次搜索局部(Local)、嵌套(Enclosing)、全局(Global)和内建(Built-in)作用域,全局变量需用global声明才能在函数内修改,嵌套变量用nonlocal声明可修改。函数调用时开辟栈帧存储局部变量,调用结束后释放。递归函数通过自身调用解决子问题,需包含终止条件避免无限递归,常见应用如阶乘计算、斐波那契数列等。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值