python列表中的深浅copy

列表中的赋值和平常的赋值是不一样的,看下面的代码:

In [1]: a = 1

In [2]: b = a

In [3]: a
Out[3]: 1

In [4]: b
Out[4]: 1

In [5]: id(a)
Out[5]: 4452948992

In [6]: id(b)
Out[6]: 4452948992

In [7]: id(1)
Out[7]: 4452948992

In [8]: a = 4

In [9]: b
Out[9]: 1

In [10]: id(a)
Out[10]: 4452949088

In [11]: id(b)
Out[11]: 4452948992

In [12]: id(1)
Out[12]: 4452948992

在这段代码中,a = 1,a指向内存地址;b = a,b也指向内存地址1,所以当a指向内存地址4的时候,b的值不变,因为b指向的内存地址是1而不是a。

在列表中就不一样了,下面介绍列表的深浅copy

1.直接赋值

In [1]: li = [1,2,3]

In [2]: n = li

In [3]: li
Out[3]: [1, 2, 3]

In [4]: n
Out[4]: [1, 2, 3]

In [5]: li[0] = ‘a‘

In [6]: li
Out[6]: [‘a‘, 2, 3]

In [7]: n
Out[7]: [‘a‘, 2, 3]

In [8]: id(li)
Out[8]: 4342626376

In [9]: id(n)
Out[9]: 4342626376

In [10]: id([1,2,3])
Out[10]: 4440762824
 
可以看出,在列表中,n是指向了li的内存地址, 不是列表[1,2,3]了,所以li的值变化的话,n也跟着变化。可以想象成li和n都指向了一个水杯,水杯里有三块白糖,把其中一块换成了黑糖,那不管是用li还是n,水杯里现在都是有两块白糖和一块黑糖。

2.浅copy
In [1]: li2 = [1,2,3,[‘alex‘,27]]

In [2]: n2 = li2.copy()

In [3]: li2
Out[3]: [1, 2, 3, [‘alex‘, 27]]

In [4]: n2
Out[4]: [1, 2, 3, [‘alex‘, 27]]

In [5]: id(li2),id(n2)
Out[6]: (4536317192, 4536271560)

In [6]: li2[0] = ‘a‘

In [7]: li2
Out[7]: [‘a‘, 2, 3, [‘alex‘, 27]]

In [8]: n2
Out[8]: [1, 2, 3, [‘alex‘, 27]]

In [9]: id(li2[0]),id(n2[0])
Out[9]: (4509371784, 4506651648)

两个列表的内存地址(id)是一样的,但是当li2里面的元素改变后,n2里的元素并没有改变,等于是只把列表(杯子)copy过去了,没有把列表里的元素(糖块)copy过去,里面的元素(糖块)不是共享的。改里面的元素就和最一开始说的a=1,b=a,a=5一样的.li[0]指向了别的内存地址,n2[0]还是指向1,所以内存地址就不一样了。

下面就不一样了

In [10]: li2[3][0] = ‘帅哥‘

In [11]: li2
Out[11]: [‘a‘, 2, 3, [‘帅哥‘, 27]]

In [12]: n2
Out[12]: [1, 2, 3, [‘帅哥‘, 27]]

In [13]: id(li2[3]),id(n2[3])
Out[13]: (4536316872, 4536316872)

In [15]: id(li2[3][0])
Out[15]: 4536362680    # 和li2[3]的内存地址不一样

li2[3]和li2[3][0]的内存地址并不一样。 原因是li2[3]指的是整个列表([‘帅哥‘, 27],就当做大杯子里的小杯子),这等于只是copy了小杯子的内存地址,里面的东西(元素)还是共享的,也就是li2和n2共享这个小列表里面的内容。

4.深copy(不太常用)

In [1]: import copy

In [2]: li3 = [1,2,3,[‘alex‘,27]]

In [3]: n3 = copy.deepcopy(li3)

In [4]: li3
Out[4]: [1, 2, 3, [‘alex‘, 27]]

In [5]: n3
Out[5]: [1, 2, 3, [‘alex‘, 27]]

In [6]: li3[3][0] = ‘帅哥‘

In [7]: li3
Out[7]: [1, 2, 3, [‘帅哥‘, 27]]

In [8]: n3
Out[8]: [1, 2, 3, [‘alex‘, 27]]

可以看出,等于是完全copy了一份,除非特殊场景这个方法不常用,也不建议用,因为如果列表存的数据量特别大的话,这样深copy一份直接翻一倍,浪费空间。

原文地址:https://www.cnblogs.com/lshedward/p/9912081.html

时间: 2024-11-12 22:54:09

python列表中的深浅copy的相关文章

python列表中添加对象时的注意

最近在用python写代码,用到了对象数组.在c++中我们要使用能够灵活操作的对象数组,一般会用stl的vector类,该类的push_back方法可以将一个对象的拷贝加入到vector对象中,所以当使用[]下标对vector的元素进行修改时,原来的作为push_back参数的那个对象的值并不会改变.python中类似的方法是列表的append方法,但是要注意此时若加入到列表中的是基础数据类型,则是值传递,若是对象,则是引用传递.这种参数的传递方式和java一样.因此,在python中通过列表下

python中的深浅Copy

二,深浅copy 1,先看赋值运算. l1 = [1,2,3,['barry','alex']] l2 = l1 l1[0] = 111 print(l1) # [111, 2, 3, ['barry', 'alex']] print(l2) # [111, 2, 3, ['barry', 'alex']] l1[3][0] = 'wusir' print(l1) # [111, 2, 3, ['wusir', 'alex']] print(l2) # [111, 2, 3, ['wusir',

python之集合、深浅copy、文件操作、函数初识

本节内容:集合.深浅copy.文件操作.函数初识 1.小知识点补充 2.编码二 3.集合 4.深浅copy 5.文件操作 6.函数的初识 1.小知识点补充                                                                                           1.1 小数据池====str.int 小数据池存在的意义就是节省内存 节省内存,位多个变量开辟一个共享空间(str和int) int:-5--256 int===

Python列表中包含中文时输出十六进制转中文的小方法

现象:列表中的中文打印出来后显示为十六进制 >>> lt=['大神','zhzhgo'] >>> print lt ['\xb4\xf3\xc9\xf1', 'zhzhgo'] >>> 首先需要明确,这不是乱码,这是 unicode 字符串在内存中的形式,python 在命令行界面输出的数据,如果不是ASCII码,则会以十六进制形式输出. 如何使打印出来的结果显示为中文呢?解决办法如下: #-*-coding:utf-8-*- lt=["大神

python列表中常用方法

#Author:yue#列表li=[1,2,3,4,5]# 1.值的追加# li.append(5)# print(li)# [1, 2, 3, 4, 5, 5]# li.append('yue')# print(li)# [1, 2, 3, 4, 5, 'yue']# 2.清空列表# li.clear()# print(li)# [] # 3 复制 浅拷贝# v = li.copy()# print(li)# print(v)## [1, 2, 3, 4, 5]# [1, 2, 3, 4, 5

python列表中的pop函数

再python的列表中,有许多的内置方法,而在这里我主要向大家介绍一下pop函数. pop函数主要是用于删除列表中的数据.而其删除值时会返回删除的值.如果没有参数传入时, 则会默认认为删除列表的最后一项数据. 如: a = ["ss",'nn','cc'] print(a.pop(1))运行结果就是nn如果是print(a.pop())运行结果就是:cc 原文地址:https://www.cnblogs.com/bao9687426/p/9813041.html

Python列表操作与深浅拷贝(7)——列表深浅拷贝、删除、反转、排序

列表复制 浅拷贝:简单类型元素全复制,引用类型元素只复制引用 L1 = [3,2,1,[4,5,6],8,'abc'] L1 [3, 2, 1, [4, 5, 6], 8, 'abc'] L2 = L1.copy() L2 [3, 2, 1, [4, 5, 6], 8, 'abc'] L1[3][1] = 10 #修改L1中的元素L2也随之变化 L1 [3, 2, 1, [4, 10, 6], 8, 'abc'] L2 [3, 2, 1, [4, 10, 6], 8, 'abc'] 深拷贝:co

pyhton中的深浅copy

深浅拷贝:数据分离情况 1. =赋值:数据完全共享(指向内存中的同一个对象)被赋值的变量指向的数据和原变量的数据都是指向内存中的同一个地址: (1)如果是不可变数据类型(数字.字符串等),修改其中的一个值,实际是修改了变量指向与值对应的地址(相当于重新被赋值),因此会同时发生变化: (2)如果是可变数据类型(列表.字典等),在修改数据时仅仅是其本身的地址指向发生了改变,但是指向可变数据类型的地址并未改变,因此会同时发生改变. 1 print("以下是赋值") 2 a=[1,2,&quo

python列表中enumerate和zip函数用法

enumerate: 定义:enumerate() 函数用于将一个可遍历的数据对象(如列表.元组或字符串)组合为一个索引序列,同时列出数据和数据下标 例子: 1 list1 =[89,98,00,75,68,37,58,90] 2 for index,item in enumerate(list1): 3 if str(item)!='0': 4 list1[index]=int('19'+str(item)) 5 else: 6 list1[index]=int('200'+str(item)