【问题标题】:Slicing assignment, shallow/deep copy切片分配,浅/深拷贝
【发布时间】:2017-11-06 12:03:05
【问题描述】:

所以,我明白了:

a_list = [1,2,3]
b_list = [5,6,7]
a_list.append(b_list) 

a_list 目前是[1,2,3, [5,6,7]]

c_list = a_list[:]
b_list[0] = 1000
print(a_list, c_list)

a_list 是[1,2,3,[1000,6,7]]

c_list 是[1,2,3,[1000,6,7]]

a_listc_list 都发生了变化,因为当 b_list 附加到 a_list 时,b_list 是对 [5,6,7] 的引用,并且对 b_list 的任何更改都会显示 a_listc_list。那挺好的。

问题是当你有:

a_list = [1, 2, [1,5,0]]
b_list = a_list[:]
a_list[2][1] = 90000
print(a_list, b_list)

a_list[1, 2, [1, 90000, 0]]b_list[1, 2, [1, 90000, 0]]

为什么b_list 发生了变化? b_lista_list 的浅拷贝,如果它有引用,它将复制引用,而不是实际的对象。 但是,a_list 没有复制引用;它是一个精确值,一个数字列表,如果 a_list 中的某些值发生更改,b_list 不应更改,因为它们完全不同,b_list 不是通过赋值指向a_list

【问题讨论】:

  • 嵌套列表仍然是参考。变量是命名引用,列表中的索引是编号引用。
  • 浅拷贝是一个新列表,其元素与原始列表的元素相同(这些元素的不是个副本)。如果要递归复制元素,请使用copy.deepcopy

标签: python slice deep-copy shallow-copy


【解决方案1】:

一切在 Python 中都是参考。列表索引只是引用,就像名称(变量)一样。

所以a_list[2] 是对列表对象的引用,就像a_list[0] 是对整数对象的引用一样。您创建了 a_list 的浅表副本,这意味着所有 3 个引用都被复制到了一个新的列表对象。

所以,b_list[2] 引用与 a_list[2] 相同的对象,另一个列表对象。通过a_list[2]b_list[2] 修改该列表对象将使更改可见。

如果您还需要复制引用的对象,请创建深层副本。您可以使用 copy.deepcopy() 递归地复制所有内容,或者使用列表推导式仅创建直接嵌套列表的浅表副本。

【讨论】:

    猜你喜欢
    • 2012-04-12
    • 2013-10-04
    • 1970-01-01
    • 2015-01-13
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多