2016-12-15 32 views
2

我遇到了一个(在我看来)非常奇怪的行为,当循环通过列表的列表。这是很难解释的,但这里有一个例子代码:为什么一个循环槽列表不能识别,列表是一个副本

k = [[0],[1],[2]] 

for lis in k: 
    lis_copy = lis 
    lis_copy.append(0) 
    print lis 

当执行这一点,我得到:

[0, 0] 
[1, 0] 
[2, 0] 

这对我来说是很奇怪的,作为附加列出的是一个lis的副本, 但是lis也被附加。我会假设这个列表是未触及的。 例如做同样与整数列表将发生以下情况:

k = [0,1,2] 

for num in k: 
    num_copy = num 
    num_copy = 0 
    print num 

输出:

0 
1 
2 

正如预期NUM不受num_copy的操作感动。

如果有人可以解释为什么会发生这种情况,以及如何避免这种情况, 就像如何断开lis_copy与is,那会很好。

哇,我很惊讶我没有遇到过市长问题,不知道这一点。我想我应该检查一下我的代码。无论如何,我认为这是某种方式连接到环,这似乎不是如此,因此,我认为最好的解释可以在这里找到:

How to clone or copy a list?

+0

http://stackoverflow.com/questions/184710/what深度复制和浅度复制之间的区别 –

+0

https://docs.python.org/3/library/copy.html –

+0

我想你'在这里重新丢失了关于Python的一些关键知识 - 请阅读本文以获得有关调用参考和按名称调用的概述: http://www.python-course.eu/passing_arguments。php – wilfo

回答

1

你可以使用copy.copy()copy.deepcopy(),以避免此行为:

import copy 

k = [[0],[1],[2]] 

for lis in k: 
    lis_copy = copy.copy(lis) 
    lis_copy.append(0) 
    print lis 

输出:

[0] 
[1] 
[2] 

来源:https://docs.python.org/2/library/copy.html

2

这是因为Python列表(和类型的字典)不复制到新列表中,但新列表成为对该列表的引用。如果你真的要复制的列表,使用deepcopy的

+0

可以举一个例子,为什么需要引用列表的副本,我只是想知道该行为的优势在哪里? –

1

案例一:

k = [[0],[1],[2]] 

for lis in k: 
    lis_copy = lis 
    lis_copy.append(0) 
    print lis 

我们有一个指针列表,并在循环内,我们有另一个指针来指向内部列表对象。然后将零附加到每个对象。

案例B:

k = [0,1,2] 

for num in k: 
    num_copy = num 
    num_copy = 0 
    print num 

我们有一个指针列表,并在循环内,我们有另一个指针来指向内的整数。不同的是,在这种情况下,指针被改变为指向零对象而不是列表元素。

相关问题