0%

Python中=、copy()和deepcopy()的区别

  • 数值,字符串str,元组tuple类型变量为静态变量(不可变对象)。
  • 列表list,字典dict,集合set类型变量为动态变量(可变对象)。

直接赋值:对象的引用(别名)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# a, b为数值类型
a = 1
b = a
print(a == b) # True
print(a is b) # True

# a, b为字符串(str)类型
a = 'abcdefg'
b = a
print(a == b) # True
print(a is b) # True

# a, b为元组(tuple)类型
a = (1, 2, 3)
b = a
print(a == b) # True
print(a is b) # True

# a, b为列表(list)类型
a = [1, 2, 3]
b = a
print(a == b) # True
print(a is b) # Ture
a.append(5)
print(a == b) # True
print(a is b) # True

# a, b为集合(set)类型
a = {1, 2, 3}
b = a
print(a == b) # True
print(a is b) # Ture

# a, b为字典(dict)类型
a = {1: 'aaa', 2: 'bbb', 3: "ccc"}
b = a
print(a == b) # True
print(a is b) # Ture

# a, b为含子对象的组合类型
a ={'l': [1, 2, 3, 4, 5], "i": 11}
b = a
print(a == b) # True
print(a is b) # Ture

a['l'][0] = 11
a['i'] = 12
print(a) # {'l': [11, 2, 3, 4, 5], 'i': 12}
print(b) # {'l': [11, 2, 3, 4, 5], 'i': 12}
print(a is b) # True

copy:copy模块的copy()方法拷贝组合对象时,拷贝父对象,不会拷贝对象的内部的子对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import copy
# a, b为数值类型
a = 1
b = copy.copy(a)
print(a == b) # True
print(a is b) # True

# a, b为字符串(str)类型
a = 'abcdefg'
b = copy.copy(a)
print(a == b) # True
print(a is b) # True

# a, b为元组(tuple)类型
a = (1, 2, 3)
b = copy.copy(a)
print(a == b) # True
print(a is b) # True

# a, b为列表(list)类型
a = [1, 2, 3]
b = copy.copy(a)
print(a == b) # True
print(a is b) # False

# a, b为集合(set)类型
a = {1, 2, 3}
b = copy.copy(a)
print(a == b) # True
print(a is b) # False

# a, b为字典(dict)类型
a = {1: 'aaa', 2: 'bbb', 3: "ccc"}
b = copy.copy(a)
print(a == b) # True
print(a is b) # False

# a, b为含子对象的组合类型
a ={'l': [1, 2, 3, 4, 5], "i": 11}
b = copy.copy(a)
print(a == b) # True
print(a is b) # False

a['l'][0] = 11
print(a == b) # True
print(a) # {'l': [11, 2, 3, 4, 5], 'i': 11}
print(b) # {'l': [11, 2, 3, 4, 5], 'i': 11}
print(a is b) # False
print(a['l'] is b['l']) # True

a['i'] = 12
print(a == b) # False
print(a) # {'l': [11, 2, 3, 4, 5], 'i': 12}
print(b) # {'l': [11, 2, 3, 4, 5], 'i': 11}
print(a is b) # Flase
print(a['l'] is b['l']) # True

deepcopy:copy模块的deepcopy()方法处理含子对象的组合变量时,完全拷贝了父对象及其子对象。深拷贝会完全复制原变量相关的所有数据,在内存中生成完全一样的内容,在这个过程中对这两个变量中的一个进行任意修改都不会影响其他变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import copy
# a, b为数值类型
a = 1
b = copy.deepcopy(a)
print(a == b) # True
print(a is b) # True

# a, b为字符串(str)类型
a = 'abcdefg'
b = copy.deepcopy(a)
print(a == b) # True
print(a is b) # True

# a, b为元组(tuple)类型
a = (1, 2, 3)
b = copy.deepcopy(a)
print(a == b) # True
print(a is b) # True

# a, b为列表(list)类型
a = [1, 2, 3]
b = copy.deepcopy(a)
print(a == b) # True
print(a is b) # False

# a, b为集合(set)类型
a = {1, 2, 3}
b = copy.deepcopy(a)
print(a == b) # True
print(a is b) # False

# a, b为字典(dict)类型
a = {1: 'aaa', 2: 'bbb', 3: "ccc"}
b = copy.deepcopy(a)
print(a == b) # True
print(a is b) # False

# a, b为含子对象的组合类型
a ={'l': [1, 2, 3, 4, 5], "i": 11}
b = copy.deepcopy(a)
print(a == b) # True
print(a is b) # False

a['l'][0] = 11
print(a == b) # False
print(a) # {'l': [11, 2, 3, 4, 5], 'i': 11}
print(b) # {'l': [1, 2, 3, 4, 5], 'i': 11}
print(a is b) # False
print(a['l'] is b['l']) # False

a['i'] = 12
print(a == b) # False
print(a) # {'l': [11, 2, 3, 4, 5], 'i': 12}
print(b) # {'l': [1, 2, 3, 4, 5], 'i': 11}
print(a is b) # Flase
print(a['l'] is b['l']) # False

总结:

  • 变量的赋值均为引用(传址)。
  • 变量的copy()过程中不明确区分拷贝(传值)和引用(传址)。一般对静态变量的copy为引用(传址),对动态变量的copy为拷贝(传值);
  • 变量的deepcopy()在对一般静态变量和动态变量的处理上和copy()相同。
  • 静态变量有时存在组合现象,比如字典中包含列表,列表中包含字典,但其数据类型是最外层类型,对变量的处理也遵循该数据类型。与非组合类型的区别在于对子对象的处理:deepcopy()拷贝(传值)子对象,而copy()对子对象引用(传址)。
    • b = a:赋值引用,a和b都指向同一个对象。
    • b = copy.copy(a):浅拷贝,a和b是独立的对象,但其子对象指向同一对象(引用)。
    • b = copy.deepcopy(a):深度拷贝,a和b完全拷贝了父对象及其子对象,两者完全独立。
天生我材必有用,千金散尽还复来~
  • 本文作者: XTLei
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
-------------本文结束感谢您的阅读-------------