繁体   English   中英

即使在函数内或函数外复制,Python仍会覆盖参数

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

我的第一个问题在这里。 我希望我能使它尽可能清晰和有益。

我目前正在使用python,并且是它的新手。 不过,我喜欢这种语言,它有很多简化之处,使您的代码非常简洁。

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

这里的功能:我正在谈论的参数是resultsvalidationparam 这可能是一个直截了当的错误,因为我已经凝视了一段时间,但是我无法在Internet上找到问题的答案。

    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是一个dict,因此您可以使用resultsvalidation = resultsvalidationparam.copy()创建它的副本。 但是,这只会进行浅表复制,因此将不会复制其中包含的任何对象。 这将复制一个深层副本:

import copy
resultsvalidation = copy.deepcopy(resultsvalidationparam)

为此,对可变和不可变类型有很好的了解会有所帮助。 看到这里一个很好的解释

简而言之,假设您要传递的论点是这样的

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

现在,如果我们:

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

然后我们更改temp的值:

temp['a'] = 8

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

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

与您的问题一样,即使我们将参数复制到temp变量并更改温度,参数也会更改。

Python数据模型

价值可以改变的对象被认为是可变的。 创建后其值不可更改的对象称为不可变的。 (当更改可变对象的值时,包含对可变对象的引用的不可变容器对象的值可以更改;但是该容器仍被认为是不可变的,因为它所包含的对象的集合无法更改。因此,不可变性并不是严格意义上的与具有不变的值一样,它更加微妙。)对象的可变性由其类型决定; 例如,数字,字符串和元组是不可变的,而字典和列表则是可变的。

因此,您要使两个变量都指向同一个对象-更改对象时,它们都将指向同一对象而更改。 例如,如果要复制副本以处理字典,请尝试

dict2 = dict(dict1)

或者也dict2 = dict1.copy()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM