python学习内存地址及深/浅拷贝

Posted 所谓双鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python学习内存地址及深/浅拷贝相关的知识,希望对你有一定的参考价值。

1、有重复数据的list循环

l= [1,1,2,3,4,5,6,8] #循环删除list里面的数据的时候,结果会不正确
for i in l:
    if i%2 !=0:
        l.remove(i)
print(l)

输出结果为:

[1, 2, 4, 6, 8]

为什么会不正确呢,因为:循环下标为0元素是1,有余数就删掉了此时的list变为[1,2,3,4,5,6,8],这个时候要循环下标为1的,此时下标为0的还是1,下标为1的是2,所以下标为0的已经循环过了,所以就被漏掉了。

2、内存地址

内存地址一样

l= [1,1,2,3,4,5,6,8]
l2=l
print(id(l))
print(id(l2))

输出结果为:

1073512056648
1073512056648

所以下面这段程序,l2和l的内存地址一样,循环l2里面的元素,除去l里面的元素,那么在去除l的元素时,l2的元素也被删掉了,所以列表的重复数据没有办法删除

l= [1,1,2,3,4,5,6,8]
l2 = l
for i in l2:
    if i%2 !=0:
        l.remove(i)
print(l)

结果为:

[1, 2, 4, 6, 8]

内存地址不一样

l= [1,1,2,3,4,5,6,8]
l2 = [1,1,2,3,4,5,6,8]
print(id(l))
print(id(l2)) 

输出结果:

893515204424
893515235208

下面这段程序,l2和l的内存地址不一样,根据l2的元素进行循环,然后剔除l里面不合适的元素,最后输出l

l= [1,1,2,3,4,5,6,8]
l2 = [1,1,2,3,4,5,6,8]
for i in l2:
    if i%2 !=0:
        l.remove(i)
print(l)

3、浅拷贝

1)浅拷贝,指向的内存空间一样

l= [1,1,2,3,4,5,6,8]
l2=l
print(id(l))
print(id(l2))

输出结果是同一内存地址:

786658122440
786658122440

 2)浅拷贝举例1

lis=[1,1,2,3,4,5,6,8]
l2=lis
l2.append(测试)
print(lis)   

l2增加了元素,lis也会增加元素,因为是同一个内存空间,所以结果如下:

[1, 1, 2, 3, 4, 5, 6, 8, 测试]

3)浅拷贝举例2

lis=[1,1,2,3,4,5,6,8]
l2=lis
lis.remove(8)
print(l2) 

移除lis里的元素,l2的元素也会被移除,因为是同一个内存空间,所以结果如下:

[1, 1, 2, 3, 4, 5, 6]

4、深拷贝

1)深拷贝会重新开辟一个内存空间出来

l= [1,1,2,3,4,5,6,8]
l2=copy.deepcopy(l)
print(id(l))
print(id(l2)) 

输出结果可以发现,两个列表不是一个内存空间:

41507400
41507592

2)深拷贝举例1

lis=[1,1,2,3,4,5,6,8]
l2=copy.deepcopy(lis)
l2.append(测试)
print(lis)

l2增加了元素,但因为是深拷贝,lis和l2的内存空间不一样,所以lis不会增加元素,所以结果为:

[1, 1, 2, 3, 4, 5, 6, 8]

3)深拷贝举例2

lis=[1,1,2,3,4,5,6,8]
l2=copy.deepcopy(lis)
lis.remove(8)
print(l2)   

移除lis里的元素,l2的元素不会被移除,因为内存空间不一样,所以结果如下:

 

[1, 1, 2, 3, 4, 5, 6, 8]

 

以上是关于python学习内存地址及深/浅拷贝的主要内容,如果未能解决你的问题,请参考以下文章

C#设计模式:原型模式(Prototype)及深拷贝浅拷贝

JAVA中对象的克隆及深拷贝和浅拷贝

python学习系列--深拷贝和浅拷贝

Python中的赋值深拷贝与浅拷贝(内存地址)

python:深拷贝,浅拷贝,内存管理

python学习之深浅拷贝