Python 为什么我原来的名单会改变?

Python 为什么我原来的名单会改变?,python,list,function,Python,List,Function,我编写了一个函数SwapCities,它能够交换列表中的条目3和条目4 所以f.e[0,1,2,3,4]应该变成[0,1,2,4,3]。这个函数工作得很好,但奇怪的是,我原来的列表也发生了变化,这是我不想看到的 这是我的代码: def SwapCities(solution): n = 3##randint(0,NumberOfCities-1) m = 4##randint(0,NumberOfCities-1) result = solution temp1

我编写了一个函数SwapCities,它能够交换列表中的条目3和条目4

所以f.e[0,1,2,3,4]应该变成[0,1,2,4,3]。这个函数工作得很好,但奇怪的是,我原来的列表也发生了变化,这是我不想看到的

这是我的代码:

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

我得到以下结果:

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?!)
正如你所看到的,我原来的解决方案改变了,这是不应该的

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

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
指向与
incumberntsolution
相同的列表,因此
incumberntsolution
中的值也会更改


要保留
现有解决方案中的原始值
,请制作列表的新副本:

tmpsolution = list(IncumbentSolution)
import copy
tmpsolution = copy.deepcopy(IncumbentSolution)
创建原始列表的浅表副本。由于
IncumbentSolution
的内容是不可变的数字,一个浅拷贝就足够了。如果内容包括,例如,
dicts
,这些内容也发生了变异,那么您需要制作列表的深度副本:

tmpsolution = list(IncumbentSolution)
import copy
tmpsolution = copy.deepcopy(IncumbentSolution)

这是因为您修改了函数中的列表

通过将列表传递给函数,您只需创建对同一对象的另一个引用,
解决方案
现有解决方案
实际上指向同一个列表对象

您应该使用
InbumbentSolution[:]
将浅拷贝传递给函数

>>> 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)

关于复制列表:值得注意的是,在Python中进行交换不需要临时变量-
solution[n],solution[m]=solution[m],solution[n]
。这更简短、可读性更强、效率更高。可能重复:我总是建议使用
list(现任解决方案)
。它做同样的工作,但更具可读性
[:]
通常会让Python的新用户感到困惑(看看单凭这一点就有多少问题),虽然这并不总是不使用某些东西的好理由,但这是因为我们手头有更好的替代品。@Lattyware:好主意。使用
arr[:]
会令人困惑,尤其是在使用
NumPy
时,因为在那里它返回的是一个视图,而不是副本。