为什么循环列表列表无法识别,列表是副本

时间:2016-12-15 16:06:09

标签: python python-2.7 list

我在循环列表列表时遇到了(在我看来)非常奇怪的行为。这很难解释,但这是一个示例代码:

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_copy的操纵。

如果有人能解释为什么会这样,以及如何避免这种情况, 比如如何断开lis_copy与is的连接,那就太好了。

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

How to clone or copy a list?

3 个答案:

答案 0 :(得分:2)

这是因为Python列表(和dicts)不会复制到新列表,但新列表将成为对该列表的引用。如果您确实要复制列表,请使用deepcopy

答案 1 :(得分:1)

案例a:

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

我们有一个指向列表的指针,在循环内部我们有另一个指向内部整数的指针。区别在于,在这种情况下,指针被更改为然后指向零对象而不是列表元素。

答案 2 :(得分: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