一、深浅拷贝

核心概念:Python变量存储的是对象的引用(内存地址),而非数据本身。深浅拷贝的区别,本质就是“新对象的引用指向哪里”。

用人话理解

  • 浅拷贝 = 藕断丝连(只复制外层,内部嵌套的可变对象还是共享的)
  • 深拷贝 = 完全独立(全部复制,原对象怎么改都不影响新对象)

核心区别:是否复制嵌套的可变对象(如列表里的列表)。

1. 三种操作对比(核心示例)
import copy

names = [1, 2, [3, 4]]

# 直接赋值:共享同一内存,改一个全变
names1 = names

# 深拷贝:完全独立,互不影响
names2 = copy.deepcopy(names)
names2[0] = 5
print(names2)  # [5, 2, [3, 4]]
print(names)   # [1, 2, [3, 4]]  不变

# 浅拷贝:只复制外层,内层列表共享
names3 = copy.copy(names)
names3[0] = 6
print(names3)  # [6, 2, [3, 4]]
print(names)   # [1, 2, [3, 4]]  外层不受影响

# 修改嵌套元素,浅拷贝跟着变,深拷贝不受影响
names[2][0] = 77
print(names)   # [1, 2, [77, 4]]
print(names3)  # [6, 2, [77, 4]] 浅拷贝跟着变了
print(names2)  # [5, 2, [3, 4]]  深拷贝不受影响
2. 深浅拷贝核心区别表
操作 创建新外层容器 嵌套可变对象共享 改嵌套元素影响原数据
直接赋值 = 完全共享 影响
浅拷贝 共享 影响
深拷贝 不共享 不影响
3. 常用实现方式
数据类型 浅拷贝方式 深拷贝方式
列表 list.copy() / lst[:] / copy.copy() copy.deepcopy()
字典 dict.copy() / copy.copy() copy.deepcopy()
集合 set.copy() / copy.copy() copy.deepcopy()
4. 实用注意点
  • 不可变对象无需拷贝:字符串、数字、内部无可变元素的元组,拷贝后仍指向同一内存,修改直接创建新对象,无需区分深浅拷贝。
  • 无嵌套用浅拷贝:如果数据没有嵌套可变对象,浅拷贝效率更高(深拷贝递归复制,耗时耗内存)。
  • 循环引用慎用深拷贝:如 a=[1]; b=[a]; a.append(b) 会导致深拷贝变慢。

深浅拷贝总结

  1. 浅拷贝:只复制外层,内部嵌套可变对象仍共享。
  2. 深拷贝:完全独立,修改任何层级互不影响。
  3. 选择原则:无嵌套用浅拷贝,有嵌套且需独立用深拷贝,仅需引用用直接赋值。

二、函数基础定义与调用

函数:组织好的、可重复使用的代码段,能提高代码复用率和可读性。用 def 关键字定义,通过函数名调用。

1. 基础语法
def 函数名(参数1, 参数2, ...):
    """函数文档字符串(可选,说明功能)"""
    # 函数体(要执行的代码)
    执行逻辑
    return 返回值  # 可选,无return则返回None

# 调用函数
结果 = 函数名(1,2, ...)
2. 三种基本形式
# 无参数,无返回值
def names():
    print("你好呀,我是函数,我被调用了")
names()  # 可重复调用

# 有参数,无返回值
def name(a):
    print(f"你好,我是{a}")
name("张三")

# 有参数,有返回值
def jk(a, b):
    return a + b
result = jk(1, 2)
print(result)
3. 函数的参数(核心重点)

参数是函数的“输入”,Python支持多种参数类型:

2.1 位置参数(必选参数)
最基础的参数,调用时必须按顺序传递,数量要匹配。

def names(name, age):
    print(f"这是:{name}, 这是{age}")
names("张三", 18)  # 必须按顺序

2.2 默认参数
定义时给参数指定默认值,调用时可省略该参数。

def names(name, age=18):  # age是默认参数
    print(f"这是:{name}, 这是{age}")
names("张三")       # 使用默认值age=18
names("王五", 20)   # 覆盖默认值

注意:默认参数必须放在位置参数后面,默认值最好用不可变对象。

2.3 关键字参数
调用时通过 参数名=值 传参,顺序可任意。

def names(name, age):
    print(f"这是:{name}, 这是{age}")
names(name="张三", age=18)
names(age=20, name="王五")  # 顺序可以乱

2.4 可变长度参数(*args**kwargs
处理“不确定数量的参数”,高频用法:

*args:接收任意数量的位置参数,打包成元组

def names(*args):
    print(args)
names("张三", 18)           # ('张三', 18)
names("张三", 18, "上海")   # ('张三', 18, '上海')

**kwargs:接收任意数量的关键字参数,打包成字典

def names(**kwargs):
    print(kwargs)
names(name="张三", age=18)                    # {'name': '张三', 'age': 18}
names(name="张三", age=18, city="上海")       # {'name': '张三', 'age': 18, 'city': '上海'}

解包参数(结合拆包)

def names(name, age):
    print(f"这是:{name}, 这是{age}")

names(*["张三", 18])    # 用*解包列表
names(*("张三", 18))    # 用*解包元组

三、函数的操作

1. 函数的返回值
  • return 返回结果,执行到 return 函数立即结束。
  • returnreturn 后无值,默认返回 None
  • 可返回多个值,本质是返回元组(自动打包),接收时可拆包。
# 返回单个值
def get_unit(num):
    if num >= 100:
        return '百'
    elif num >= 10:
        return '十'
    else:
        return '个'

print(get_unit(10))  # '十'

# 返回多个值
def get_unit(num):
    if num >= 100:
        return '百', '看这里'
    elif num >= 10:
        return '十', '看这里'
    else:
        return '个', '看这里'

result, msg = get_unit(10)  # 拆包接收
print(result, msg)  # 十 看这里
2. 函数的作用域
  • 局部变量:函数内部定义的变量,仅在函数内生效,外部无法访问。
  • 全局变量:函数外部定义的变量,全局生效,函数内可读取(但修改需加 global 关键字)。
# 局部变量
def names():
    name = "张三"
    print(name)

names()
# print(name)  # 报错,访问不到局部变量

# 全局变量
name = "张三"
def names():
    print(name)  # 可以读取全局变量

names()
print(name)
3. 匿名函数(lambda)

lambda 定义极简函数,适用于一行代码的简单逻辑。

语法:lambda 参数: 表达式

# 普通写法
def add(a, b):
    return a + b
print(add(1, 2))

# 匿名函数
add = lambda a, b: a + b
print(add(1, 2))
4. 函数的复用(嵌套与递归)

嵌套函数:函数内部定义另一个函数,内层函数可访问外层函数的变量。

def outer():
    x = 10
    def inner():
        print(x + 5)  # 访问外层变量
    inner()

outer()  # 输出: 15

递归函数:函数调用自身,必须有终止条件,否则无限递归。

# 计算阶乘:n! = n * (n-1)!,终止条件: 0! = 1
def factorial(n):
    if n == 1:
        return 1
    return n * factorial(n - 1)

print(factorial(5))  # 输出: 120 (5*4*3*2*1)

今日核心总结

  1. 深浅拷贝

    • 直接赋值:共享同一内存,改一个全变。
    • 浅拷贝:只复制外层,嵌套可变对象仍共享。
    • 深拷贝:完全独立,互不影响。
    • 选择原则:无嵌套用浅拷贝,有嵌套且需独立用深拷贝。
  2. 函数核心:用 def 定义,通过函数名调用,return 返回结果(无则返回 None)。

  3. 参数类型(重点)

    • 位置参数:必须按顺序传递。
    • 默认参数:有默认值,可省略,必须放在位置参数后面。
    • 关键字参数:通过 参数名=值 传参,顺序可任意。
    • *args:接收任意数量位置参数,打包成元组。
    • **kwargs:接收任意数量关键字参数,打包成字典。
  4. 关键概念

    • 返回值:可返回多个值(本质是元组),接收时可拆包。
    • 作用域:局部变量函数内有效,全局变量全局有效。
    • lambda:一行代码的匿名函数,适合简单逻辑。
    • 递归:函数调用自身,必须有终止条件。

注:已经使用DeepSeek进行整理精简核心内容,些许不理解的配合个人笔记进行理解。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐