python 拷贝原来还有这么坑

目录

深拷贝deepcopy

示例1:修改原始对象不会影响深拷贝

示例2:浅拷贝 vs 深拷贝

示例3:深拷贝可能会引发递归错误

示例4:深拷贝带来的性能问题

总结

list拷贝copy有坑

示例1:浅拷贝只复制最外层对象

示例2:浅拷贝对不可变对象的影响

示例3:深拷贝和自引用对象

示例4:浅拷贝和深拷贝的性能差异

示例5:字典的浅拷贝

示例6:使用浅拷贝修改函数默认参数


深拷贝deepcopy

在使用 deepcopy 时,有一些常见的容易弄错的例子。deepcopy 会递归地复制一个对象及其所有子对象,这样就可以创建一个完全独立的副本。以下是几个常见的错误和误解,以及相应的示例:

示例1:修改原始对象不会影响深拷贝

import copy

original = [1, [2, 3], 4]
deep_copied = copy.deepcopy(original)

original[1][0] = 'changed'

print("Original:", original)      # Output: [1, ['changed', 3], 4]
print("Deep Copied:", deep_copied)  # Output: [1, [2, 3], 4]

容易弄错的点:有些人可能会误以为修改原始对象的子对象会影响深拷贝的对象,但实际上深拷贝对象是完全独立的。

示例2:浅拷贝 vs 深拷贝

import copy

original = [1, [2, 3], 4]
shallow_copied = copy.copy(original)
deep_copied = copy.deepcopy(original)

original[1][0] = 'changed'

print("Original:", original)            # Output: [1, ['changed', 3], 4]
print("Shallow Copied:", shallow_copied)  # Output: [1, ['changed', 3], 4]
print("Deep Copied:", deep_copied)        # Output: [1, [2, 3], 4]

容易弄错的点:浅拷贝(copy.copy)只复制了最外层对象,内部的子对象还是引用原来的对象。而深拷贝(copy.deepcopy)会复制所有层次的对象。

示例3:深拷贝可能会引发递归错误

import copy

original = [1, 2, 3]
original.append(original)

try:
    deep_copied = copy.deepcopy(original)
except RecursionError as e:
    print("RecursionError:", e)

容易弄错的点:如果对象包含自引用,使用深拷贝时需要特别小心,可能会引发无限递归错误。

示例4:深拷贝带来的性能问题

深拷贝由于需要复制所有子对象,可能会带来性能开销,特别是对于大对象。

import copy
import time

large_list = [list(range(1000)) for _ in range(1000)]

start_time = time.time()
deep_copied = copy.deepcopy(large_list)
end_time = time.time()

print("Time taken for deepcopy:", end_time - start_time)

容易弄错的点:深拷贝会比浅拷贝或者直接引用带来更大的性能开销,对于大对象需要注意这一点。

总结

使用 deepcopy 时,确保了解其行为和潜在的问题,特别是在处理复杂的嵌套对象、自引用对象以及性能敏感的场景时。

list拷贝copy有坑

import copy

if __name__ == '__main__':


    original_list = [1, 2, 3, 4, 5]
    copied_list = copy.copy(original_list)

    copied_list[0]=10
    print(original_list)

    original_list = [[1, 2, 3, 4, 5]]
    copied_list = copy.copy(original_list)

    copied_list[0][0]=10
    print(original_list)

如果list内单纯的数字,是可以的,如果list是二维,或者多维,就有坑

示例1:浅拷贝只复制最外层对象

import copy

original = [1, [2, 3], 4]
shallow_copied = copy.copy(original)

original[1][0] = 'changed'

print("Original:", original)            # Output: [1, ['changed', 3], 4]
print("Shallow Copied:", shallow_copied)  # Output: [1, ['changed', 3], 4]

示例2:浅拷贝对不可变对象的影响

import copy

original = (1, 2, 3)
shallow_copied = copy.copy(original)

# 由于元组是不可变的,shallow_copied 和 original 指向同一个对象
print("Original is shallow_copied:", original is shallow_copied)  # Output: True

示例3:深拷贝和自引用对象

import copy

original = [1, 2, 3]
original.append(original)

try:
    deep_copied = copy.deepcopy(original)
except RecursionError as e:
    print("RecursionError:", e)

示例4:浅拷贝和深拷贝的性能差异

import copy
import time

large_list = [list(range(1000)) for _ in range(1000)]

start_time = time.time()
shallow_copied = copy.copy(large_list)
end_time = time.time()
print("Time taken for shallow copy:", end_time - start_time)

start_time = time.time()
deep_copied = copy.deepcopy(large_list)
end_time = time.time()
print("Time taken for deep copy:", end_time - start_time)

示例5:字典的浅拷贝

import copy

original = {'a': 1, 'b': [2, 3]}
shallow_copied = copy.copy(original)

original['b'][0] = 'changed'

print("Original:", original)            # Output: {'a': 1, 'b': ['changed', 3]}
print("Shallow Copied:", shallow_copied)  # Output: {'a': 1, 'b': ['changed', 3]}

示例6:使用浅拷贝修改函数默认参数

import copy

def append_element(lst=None):
    if lst is None:
        lst = []
    else:
        lst = copy.copy(lst)
    lst.append(1)
    return lst

default_list = [0]
print(append_element(default_list))  # Output: [0, 1]
print(append_element(default_list))  # Output: [0, 1]  # Expected [0] due to shallow copy

容易弄错的点:在函数中使用浅拷贝复制默认参数时,原始对象会被修改,而不是创建一个新的独立对象。如果期望完全独立的对象,应该使用深拷贝。

相关推荐

  1. python 拷贝原来这么

    2024-06-09 22:28:04       30 阅读
  2. python使用dataclass数据类

    2024-06-09 22:28:04       35 阅读
  3. np.copy()是深拷贝是浅拷贝

    2024-06-09 22:28:04       57 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-09 22:28:04       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-09 22:28:04       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-09 22:28:04       87 阅读
  4. Python语言-面向对象

    2024-06-09 22:28:04       96 阅读

热门阅读

  1. 04-4.1.2 串的存储结构

    2024-06-09 22:28:04       40 阅读
  2. 【react】useEffect 快速上手

    2024-06-09 22:28:04       28 阅读
  3. android-线程池3

    2024-06-09 22:28:04       38 阅读
  4. process to develop linux 5.4

    2024-06-09 22:28:04       42 阅读
  5. 软设之排序算法对比

    2024-06-09 22:28:04       25 阅读
  6. ghidra

    2024-06-09 22:28:04       37 阅读
  7. P11 品牌管理

    2024-06-09 22:28:04       42 阅读
  8. 爬山算法的详细介绍

    2024-06-09 22:28:04       37 阅读
  9. Flutter 常见报错记录

    2024-06-09 22:28:04       49 阅读
  10. 解决更新Android Studio后下载Gradle超时

    2024-06-09 22:28:04       33 阅读