>>> person = ['name', ['savings', 100.00]]
>>> person
['name', ['savings', 100.0]]
>>> hubby = person[:]
>>> hubby
['name', ['savings', 100.0]]
>>> id(person)
29577736L
>>> id(hubby)
46633160L
>>> wifey = list(person)
>>> wifey
['name', ['savings', 100.0]]
>>> id(wifey)
46606856L
#这是一个亮点的用法,值得记录一下
>>> [id(x) for x in person, hubby, wifey]
[29577736L, 46633160L, 46606856L]
>>> person = ['name', ['savings', 100.00]]
>>> person
['name', ['savings', 100.0]]
>>> hubby = person[:]
>>> hubby
['name', ['savings', 100.0]]
>>> id(person)
29577736L
>>> id(hubby)
46633160L
>>> wifey = list(person)
>>> wifey
['name', ['savings', 100.0]]
>>> id(wifey)
46606856L
>>> [id(x) for x in person, hubby, wifey]
[29577736L, 46633160L, 46606856L]
>>> hubby[0] = 'joe'
>>> hubby
['joe', ['savings', 100.0]]
>>> wifey[0] = 'jane'
>>> wifey
['jane', ['savings', 100.0]]
>>> hubby[1][1] = 50.00
>>> hubby, wifey
(['joe', ['savings', 50.0]], ['jane', ['savings', 50.0]])
原因是我们仅仅做了一个浅拷贝。对一个对象进行浅拷贝其实是新创建了一个类型跟原对象一样,其内容是原来对象元素的引用,换句话说,这个拷贝的对象本身是新的,但是它的内容不是。序列类型对象的浅拷贝是默认类型拷贝,并可以以下几种方式实施:(1)完全切片操作[:],(2)利用工厂函数,比如list(),dict()等,(3)使用copy模块的copy函数。
当妻子的名字被赋值,为什么丈夫的名字没有受到影响?
这是因为在连个列表的两个对象中,第一个对象是不可变的(是个字符串类型),而第二个是可变的(一个列表)。正因为如此,当进行浅拷贝是,字符被显式的拷贝,并新创建了一个字符串对象,而列表元素只是把它的引用复制了一下,并不是它的成员。所以改变名字没有任何问题,但是更改他们银行账号的任何信息都会引发问题。
>>> [id(x) for x in hubby]
[43074984L, 46635592L]
>>> id(hubby)
46633160L
假设我们给这对夫妻创建一个联合账号,上面是一个非常棒的方案,但是,如果需要的是两个分离账户,就需要做些改动了。copy.deepcopy()函数,深度拷贝来重写整个例子。
>>> person = ['name', ['savings', 100.00]]
>>> hubby = person
>>> import copy
>>> wifey = copy.deepcopy(person)
>>> [id(x) for x in person, hubby, wifey]
[46632712L, 46632712L, 46646728L]
>>> hubby[0] = 'joe'
>>> wifey[0] = 'jane'
>>> person, hubby, wifey
(['joe', ['savings', 100.0]], ['joe', ['savings', 100.0]], ['jane', ['savings', 100.0]])
>>> hubby[1][1] = 50.00
>>> person, hubby, wifey
(['joe', ['savings', 50.0]], ['joe', ['savings', 50.0]], ['jane', ['savings', 100.0]])
>>> [id(x) for x in hubby]
[46919472L, 46609416L]
>>> [id(x) for x in wifey]
[43074984L, 46623816L]
关于拷贝操作的警告:
第一,非容器类型(比如数字,字符串和其他“原子”类型的对象,像代码,类型和xtange对象等)没有被拷贝一说,浅拷贝是用完全切片操作来完成的。
第二、如果元组变量只包含原子类型对象,对它的深拷贝将不会进行。如果我们把账户信息改成元组类型,那么即便按我们的要求使用深拷贝操作也只能得到一个浅拷贝:
>>> person
['name', ['savings', 100.0]]
>>> hubby = person[:]
>>> hubby
['name', ['savings', 100.0]]
>>> id(person)
29577736L
>>> id(hubby)
46633160L
>>> wifey = list(person)
>>> wifey
['name', ['savings', 100.0]]
>>> id(wifey)
46606856L
#这是一个亮点的用法,值得记录一下
>>> [id(x) for x in person, hubby, wifey]
[29577736L, 46633160L, 46606856L]
>>> person = ['name', ['savings', 100.00]]
>>> person
['name', ['savings', 100.0]]
>>> hubby = person[:]
>>> hubby
['name', ['savings', 100.0]]
>>> id(person)
29577736L
>>> id(hubby)
46633160L
>>> wifey = list(person)
>>> wifey
['name', ['savings', 100.0]]
>>> id(wifey)
46606856L
>>> [id(x) for x in person, hubby, wifey]
[29577736L, 46633160L, 46606856L]
>>> hubby[0] = 'joe'
>>> hubby
['joe', ['savings', 100.0]]
>>> wifey[0] = 'jane'
>>> wifey
['jane', ['savings', 100.0]]
>>> hubby[1][1] = 50.00
>>> hubby, wifey
(['joe', ['savings', 50.0]], ['jane', ['savings', 50.0]])
原因是我们仅仅做了一个浅拷贝。对一个对象进行浅拷贝其实是新创建了一个类型跟原对象一样,其内容是原来对象元素的引用,换句话说,这个拷贝的对象本身是新的,但是它的内容不是。序列类型对象的浅拷贝是默认类型拷贝,并可以以下几种方式实施:(1)完全切片操作[:],(2)利用工厂函数,比如list(),dict()等,(3)使用copy模块的copy函数。
当妻子的名字被赋值,为什么丈夫的名字没有受到影响?
这是因为在连个列表的两个对象中,第一个对象是不可变的(是个字符串类型),而第二个是可变的(一个列表)。正因为如此,当进行浅拷贝是,字符被显式的拷贝,并新创建了一个字符串对象,而列表元素只是把它的引用复制了一下,并不是它的成员。所以改变名字没有任何问题,但是更改他们银行账号的任何信息都会引发问题。
>>> [id(x) for x in hubby]
[43074984L, 46635592L]
>>> id(hubby)
46633160L
假设我们给这对夫妻创建一个联合账号,上面是一个非常棒的方案,但是,如果需要的是两个分离账户,就需要做些改动了。copy.deepcopy()函数,深度拷贝来重写整个例子。
>>> person = ['name', ['savings', 100.00]]
>>> hubby = person
>>> import copy
>>> wifey = copy.deepcopy(person)
>>> [id(x) for x in person, hubby, wifey]
[46632712L, 46632712L, 46646728L]
>>> hubby[0] = 'joe'
>>> wifey[0] = 'jane'
>>> person, hubby, wifey
(['joe', ['savings', 100.0]], ['joe', ['savings', 100.0]], ['jane', ['savings', 100.0]])
>>> hubby[1][1] = 50.00
>>> person, hubby, wifey
(['joe', ['savings', 50.0]], ['joe', ['savings', 50.0]], ['jane', ['savings', 100.0]])
>>> [id(x) for x in hubby]
[46919472L, 46609416L]
>>> [id(x) for x in wifey]
[43074984L, 46623816L]
关于拷贝操作的警告:
第一,非容器类型(比如数字,字符串和其他“原子”类型的对象,像代码,类型和xtange对象等)没有被拷贝一说,浅拷贝是用完全切片操作来完成的。
第二、如果元组变量只包含原子类型对象,对它的深拷贝将不会进行。如果我们把账户信息改成元组类型,那么即便按我们的要求使用深拷贝操作也只能得到一个浅拷贝: