Python中赋值运算符与列表的工作机制探究
列表与整数在赋值及修改时的ID差异问题
先看列表的赋值与修改表现:
>>> list1 = [1,2,3,4,5] >>> newlist1 = list1 >>> print(id(list1)) 140282759536448 >>> print(id(newlist1)) 140282759536448 >>> newlist1.append(6) >>> print(id(newlist1)) 140282759536448 >>> print(list1) [1, 2, 3, 4, 5, 6] >>> print(newlist1) [1, 2, 3, 4, 5, 6]
再看整数的赋值与修改表现:
>>> int1 = 1 >>> newint1 = int1 >>> print(id(int1)) 140282988331248 >>> print(id(newint1)) 140282988331248
修改整数后,ID发生变化:
>>> newint1 = newint1 + 1 >>> print(id(newint1)) 140282988331280 >>> print(id(int1)) 140282988331248
问题
- 为何修改列表不会生成新的ID?
- 如何为列表创建新的ID?
解答
为什么修改列表不生成新ID?
核心是可变对象与不可变对象的特性差异:
- 整数是不可变对象,一旦创建就无法修改其本身的值。执行
newint1 = newint1 + 1时,并没有在原整数对象上修改,而是直接创建了一个值为2的新整数对象,再让newint1指向这个新对象,因此ID会改变。 - 列表是可变对象,
append这类操作是直接在原列表对象的内存空间里修改内部数据,对象本身的内存地址(即ID)不会改变。newlist1和list1始终指向同一个列表对象,所以ID保持一致。
如何为列表创建新ID?
要生成新ID,本质是创建一个独立的新列表对象,常用方法有:
- 切片复制:
newlist = list1[:],切片操作会生成包含原列表所有元素的新列表。 - 构造函数复制:
newlist = list(list1),通过list()构造函数创建新实例。 - 列表推导式:
newlist = [x for x in list1],遍历原列表生成新列表。 - copy模块拷贝:导入
copy模块后,newlist = copy.copy(list1)(浅拷贝);若列表包含嵌套可变对象,用copy.deepcopy(list1)做深拷贝。
示例(切片复制):
>>> list1 = [1,2,3,4,5] >>> newlist1 = list1[:] >>> print(id(list1)) 140282759536448 >>> print(id(newlist1)) 140282759537024 # 新的ID >>> newlist1.append(6) >>> print(list1) [1,2,3,4,5] >>> print(newlist1) [1,2,3,4,5,6]
内容的提问来源于stack exchange,提问作者TaranYourAss
相关产品推荐
相关产品推荐

