为什么对两个相同的列表进行操作会得到不同的结果?
为什么对两个相同的列表进行操作会得到不同的结果?
我有一个Python代码,在其中首先定义了两个列表,然后使它们相同,并在它们相同后对它们进行相同的操作-但结果并不相同:
test1 = [[[0],[0]]]*2 test2 = [[0]]*2 test2[0] = [[0],[0]] test2[1] = [[0],[0]] print 'They are identical?:',test1 == test2 # 得到 True # 现在test1 == test2对列表1和2进行相同的操作: test1[0][0] = 2 test2[0][0] = 2 print test1 print test2
这会得到:
[[2, [0]], [2, [0]]] # test1 [[2, [0]], [[0], [0]]] # test2
有人能解释一下这个差异吗?
为什么对两个相同的列表进行操作会得到不同的结果?
这个问题的出现原因是,在执行test1 = [[[0],[0]]]*2
命令时,实际上等同于执行以下两个操作:
a = [[0], [0]] test1 = [a, a]
然后,当你对test1[0][0]
赋值时,实际上是改变了a
列表的值。当然,test1[1]
的值也会改变,因为它与a
列表是同一个。
解决这个问题的方法是使用深拷贝方法来创建列表。深拷贝会创建一个新的对象,而不是引用已有对象。这样,当对一个列表进行操作时,不会影响到其他相同的列表。
以下是使用深拷贝方法来解决这个问题的示例代码:
import copy a = [[0], [0]] test1 = [copy.deepcopy(a), copy.deepcopy(a)]
这样,对test1[0][0]
进行操作时,只会改变test1[0]
中的值,不会影响到test1[1]
。
操作两个相同列表为什么会得到不同的结果?
原因:
- 列表在Python中是按引用传递的。当使用乘法运算符对列表进行操作时,结果中的元素是指向同一个列表的引用。
- 这意味着对一个元素的修改会影响到其他指向同一引用的元素的值。
解决方法:
- 如果希望得到两个相同结构的列表,可以使用列表推导式或者循环来创建新的列表。
- 可以使用copy
模块中的copy
函数来创建一个新的列表,该列表与原列表具有相同的值但是指向不同的引用。
以下为示例代码和输出结果:
import copy A = [[0]] * 2 B = copy.copy([[0], [0]]) print(A[0] == A[1]) # 输出 True print(A[0] is A[1]) # 输出 True A[0].append(1) print(A) # 输出 [[0, 1], [0, 1]] print(B[0] == B[1]) # 输出 True print(B[0] is B[1]) # 输出 False B[0].append(1) print(B) # 输出 [[0, 1], [0]]
通过以上代码可以看出,使用copy
函数创建的列表B中的元素指向不同的引用,对一个元素的修改不会影响到其他元素的值。而使用乘法运算符创建的列表A中的元素指向同一个引用,对一个元素的修改会影响到其他元素的值。