Python 不断覆盖参数,即使在函数内外复制时也是如此

Python keeps overwriting argument, even when copied in or outside of function

这是我的第一个问题。我希望我能使它尽可能清晰和翔实。

我目前正在使用 python,而且是新手。不过我喜欢这种语言,大量的简化使您的代码非常简洁。

我目前有一个接受参数的函数。即使我将它复制到函数内的局部变量,该参数也会被覆盖。即使在函数外部复制(以及传递给函数的参数),它也会覆盖原始参数。

这里是函数:我说的参数是resultsvalidationparam。这可能是一个直截了当的错误,因为我已经盯着这个看了一段时间了,但我在互联网上找不到我的问题的答案。

    def mean_cluster_validation(resultsvalidationparam, validationmethods, mean_methods = 'relative'):
resultsvalidation = resultsvalidationparam
n_clusters = np.arange(2,2 + len(resultsvalidation.keys()))
clustermethods = tuple(resultsvalidation[str(2)].keys())
'''
First we find the best and worst score for each validation method (which gives a certain clustern and clustermethod). After which all scores are made
relative to those scores (giving them values between 0 and 1). Some validations methods are best when low or high values, this is taken into account. 
'''    
# Find max and min
validationMax = {}
validationMin = {}
for t in validationmethods:
    currentMax = (0,)# list containing max value, clustering method and number of clusters where value is max for certain validation method
    currentMin = (100000,)
    for i in n_clusters:
        for j in clustermethods: 
            if resultsvalidation[str(i)][j][t] is not None:
                if resultsvalidation[str(i)][j][t] > currentMax[0]:
                    currentMax = (resultsvalidation[str(i)][j][t],i,j)
                if resultsvalidation[str(i)][j][t] < currentMin[0]:
                    currentMin = (resultsvalidation[str(i)][j][t],i,j)
    validationMax[t] = currentMax
    validationMin[t] = currentMin

for t in validationmethods:
    for i in n_clusters:
        for j in clustermethods:
            if resultsvalidation[str(i)][j][t] is not None:
                resultsvalidation[str(i)][j][t] = (resultsvalidation[str(i)][j][t] - validationMin[t][0])/(validationMax[t][0] - validationMin[t][0])
return validationMax, validationMin, resultsvalidation

即使我在变量的函数之外使用副本(例如't'),它仍然会覆盖原始变量

我很困, 再次抱歉,如果我提出的问题不正确,我的英语很差。

在 python 中,赋值 resultsvalidation = resultsvalidationparam 不会创建一个副本,而是创建一个别名:resultsvalidationresultsvalidationparam 是同一个对象。您可以使用 is 运算符进行检查。

看起来 resultsvalidationparam 是一个字典,因此您可以使用 resultsvalidation = resultsvalidationparam.copy() 创建它的副本。但是,这只是一个浅拷贝,因此不会复制其中包含的任何对象。这将进行深拷贝:

import copy
resultsvalidation = copy.deepcopy(resultsvalidationparam)

为此,对可变类型和不可变类型有很好的理解会有所帮助。参见 here for a nice explanation

简而言之,假设您要通过的论点是

param = {'a': 2, 'b': 3}

现在如果我们:

temp = param 
print temp # {'a': 2, 'b': 3}

然后我们更改 temp 的值:

temp['a'] = 8

现在我们再次检查 param 并且:

print param
{'a': 8, 'b': 3}

对于您的问题,即使我们将其复制到临时变量并更改温度,参数也会发生变化。

来自the Python Data model

Objects whose value can change are said to be mutable; objects whose value is unchangeable once they are created are called immutable. (The value of an immutable container object that contains a reference to a mutable object can change when the latter’s value is changed; however the container is still considered immutable, because the collection of objects it contains cannot be changed. So, immutability is not strictly the same as having an unchangeable value, it is more subtle.) An object’s mutability is determined by its type; for instance, numbers, strings and tuples are immutable, while dictionaries and lists are mutable.

所以你让你的两个变量都指向同一个对象——当它改变时,两个变量都会改变,因为它们指向同一个东西。例如,如果你想复制一份字典来处理,试试

dict2 = dict(dict1)

或者 dict2 = dict1.copy()