[英]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
不会复制,而是一个别名: resultsvalidation
和resultsvalidationparam
是同一对象。 您可以使用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变量并更改温度,参数也会更改。
价值可以改变的对象被认为是可变的。 创建后其值不可更改的对象称为不可变的。 (当更改可变对象的值时,包含对可变对象的引用的不可变容器对象的值可以更改;但是该容器仍被认为是不可变的,因为它所包含的对象的集合无法更改。因此,不可变性并不是严格意义上的与具有不变的值一样,它更加微妙。)对象的可变性由其类型决定; 例如,数字,字符串和元组是不可变的,而字典和列表则是可变的。
因此,您要使两个变量都指向同一个对象-更改对象时,它们都将指向同一对象而更改。 例如,如果要复制副本以处理字典,请尝试
dict2 = dict(dict1)
或者也dict2 = dict1.copy()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.