关于python:为什么我的原始列表会发生变化?

Why does my original list change?

我写了一个函数swapcities,它可以交换列表中的条目3和4。

所以F.E.[0,1,2,3,4]应该变成[0,1,2,4,3]。这个函数工作得很好,但奇怪的是,我的原始列表也发生了我不想要的更改。

这是我的代码:

1
2
3
4
5
6
7
8
9
def SwapCities(solution):
    n = 3##randint(0,NumberOfCities-1)
    m = 4##randint(0,NumberOfCities-1)
    result = solution
    temp1 = solution[n]
    temp2 = solution[m]
    result[n] = temp2
    result[m] = temp1
    return result
1
2
3
4
5
6
7
8
9
print"Start"
IncumbentSolution = list(x for x in range(0,NumberOfCities))
print IncumbentSolution

print"After swap" NewSolution = SwapCities(IncumbentSolution)
print NewSolution

print"Original solution"
print IncumbentSolution

我得到以下结果:

1
2
3
4
How many cities?
8 Start [0, 1, 2, 3, 4, 5, 6, 7]
After swap [0, 1, 2, 4, 3, 5, 6, 7]
Original solution [0, 1, 2, 4, 3, 5, 6, 7]   (why did this change?!)

正如你所看到的,我原来的解决方案改变了,但它不应该这样做。

我不知道为什么会这样。即使当我更改代码使更改应用于原始列表的副本时,我也会得到这个结果。有人能解释我做错了什么吗?

1
2
3
4
5
6
7
8
9
10
11
IncumbentSolution = list(x for x in range(0,NumberOfCities))
print"Start"
print IncumbentSolution

print"After swap"
tmpsolution = IncumbentSolution
NewSolution = SwapCities(tmpsolution)
print NewSolution

print"Original solution"
print IncumbentSolution


SwapCities使solution的内容物发生突变。由于solution指向与IncumbentSolution相同的列表,因此IncumbentSolution中的值也会改变。

要保留IncumbentSolution中的原始值,请制作列表的新副本:

1
tmpsolution = list(IncumbentSolution)

对原始列表进行简单复制。由于IncumbentSolution的内容是不可变的数字,一个浅拷贝就足够了。如果内容包括,比如说,dicts也在变异,那么您需要对列表进行深入的复制:

1
2
import copy
tmpsolution = copy.deepcopy(IncumbentSolution)


这是因为您修改了函数内部的列表。

通过将列表传递给函数,您只需创建对同一对象的另一个引用,solutionIncumbentSolution实际上指向同一列表对象。

您应该使用IncumbentSolution[:]将一个浅拷贝传递给函数。

1
2
3
4
5
6
7
8
9
>>> def func(x):
...     return id(x)
...
>>> lis = range(5)
>>> id(lis),func(lis)     #both `x` and `lis` point to the same object
(163001004, 163001004)

>>> id(lis),func(lis[:])  #pass a shallow copy, `lis[:]` or `list(lis)`
(163001004, 161089068)