python中的深复制和浅复制

简单赋值,浅拷贝,深拷贝

简单赋值

str

1
2
3
4
a = 'hello'
b = 'hello'
c = a
print(id(a),id(b),id(c))

2432356754632 2432356754632 2432356754632

这里打印出a,b,c的id是一样的,因为他们全是指向’hello’这个字符串在内存中的地址

1
2
a = 'world'
print(id(a),id(b),id(c))

2432356757376 2432356754632 2432356754632

将a指向一个新的字符串’world’,所以变量a的地址就改变了,指向字符串’world’的地址,但是b和c还是指向字符串’hello’的地址。

list

1
2
3
4
a = ['hello']
b = ['hello']
c = a
print(id(a),id(b),id(c))

2432356788424 2432356797064 2432356788424

1
2
b = ['world']
print(id(a),id(b),id(c))

2432356798024 2432356797064 2432356788424

结论

简单赋值是先给一个变量分配内存,然后把变量的地址赋值给一个变量名。
对于一些不可变的类型,比如str,int等,某一个值在内存中的地址是固定的,如果用赋值操作直接指向一个值的话,那么变量名指向的就是这个值在内存中地址。
比如a=‘hello’,b=‘hello’,这样a和b的id是相同的,都指向内存中hello的地址
对于一些可变的类型,比如list,因为他是可变的,所以如果用赋值操作指向同一个值的话,那么这几个变量的地址也不一样
比如a =[‘hello’],b=[‘hello’],这样a和b的id是不同的,虽然他们指向的值是一样的,

浅拷贝

1
2
3
4
5
6
7
8
a = ['hello' , [123] ]
b = a[:]
a = ['hello' , [123] ]
b = a[:]
print(a,b)
print(id(a),id(b))
print(id(a[0]),id(a[1]))
print(id(b[0]),id(b[1]))

[‘hello’, [123]] [‘hello’, [123]]
2432356775368 2432356775432 2432356754632 2432356774984
2432356754632 2432356774984

1
2
3
4
5
>>>a[0] = 'world'
>>> print(a,b)
>>> print(id(a),id(b))
>>> print(id(a[0]),id(a[1]))
>>> print(id(b[0]),id(b[1]))

[‘world’, [123]] [‘hello’, [123]]
2432356775368 2432356775432
2432356756424 2432356774984
2432356754632 2432356774984

1
2
3
4
5
a[1].append(3)
print(a,b)
print(id(a),id(b))
print(id(a[0]),id(a[1]))
print(id(b[0]),id(b[1]))

[‘world’, [123, 3]] [‘hello’, [123, 3]]
2432356775368 2432356775432
2432356756424 2432356774984
2432356754632 2432356774984

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
a[1] = [123]
print(a,b)
print(id(a),id(b))
print(id(a[0]),id(a[1]))
print(id(b[0]),id(b[1]))
```
> ['world', [123]] ['hello', [123, 3]]
2432356775368 2432356775432
2432356756424 2432356822984
2432356754632 2432356774984

### 深拷贝
``` python
from copy import deepcopy
a = ['hello',[123,234]
b = deepcopy(a)

a,b以及a,b中任何元素(除了str,int等类型)的地址都是不一样的