[英]Python keeps overwriting argument, even when copied in or outside of function
My first question here. 我的第一个问题在这里。 I hope I can make it as clear and informative as possible.
我希望我能使它尽可能清晰和有益。
I am currently using python, and new to it. 我目前正在使用python,并且是它的新手。 I love the language though, a lot of simplifications that keep your code very concise.
不过,我喜欢这种语言,它有很多简化之处,使您的代码非常简洁。
I currently have a function that accepts an argument. 我目前有一个接受参数的函数。 That argument gets overwritten even if I copy it to a local variable inside the function.
即使我将其复制到函数内部的局部变量中,该参数也会被覆盖。 Even when copied outside of the function (and the argument passed to the function) it overwrites the original argument.
即使在函数外(以及传递给函数的参数)复制时,它也会覆盖原始参数。
Here the function: The argument I'm talking of is resultsvalidationparam
. 这里的功能:我正在谈论的参数是
resultsvalidationparam
。 It might be a straightforward mistake as I've been staring at this for a while now, but I couldn't find an answer to my problem on the Internet. 这可能是一个直截了当的错误,因为我已经凝视了一段时间,但是我无法在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
Even when I use a copy (eg 't') outside of the function of the variable, it still overwrites the original variable 即使我在变量功能之外使用副本(例如“ t”),它仍然会覆盖原始变量
I'm pretty stuck, again, apologies if I incorrectly formulated the question, my english is pretty poor. 再次,我很困惑,如果我不正确地提出问题,我会很抱歉,我的英语很差。
In python, the assignment resultsvalidation = resultsvalidationparam
doesn't make a copy, but rather an alias: resultsvalidation
and resultsvalidationparam
are the same object. 在python中,赋值
resultsvalidation = resultsvalidationparam
不会复制,而是一个别名: resultsvalidation
和resultsvalidationparam
是同一对象。 You can check this using the is
operator. 您可以使用
is
运算符进行检查。
It looks like resultsvalidationparam
is a dict, so you can create a copy of it using resultsvalidation = resultsvalidationparam.copy()
. 看起来
resultsvalidationparam
是一个dict,因此您可以使用resultsvalidation = resultsvalidationparam.copy()
创建它的副本。 However, this only makes a shallow copy, so any objects contained within it will not be copied. 但是,这只会进行浅表复制,因此将不会复制其中包含的任何对象。 This will make a deep copy:
这将复制一个深层副本:
import copy
resultsvalidation = copy.deepcopy(resultsvalidationparam)
For this, having a good understanding of mutable and immutable types help. 为此,对可变和不可变类型有很好的了解会有所帮助。 See here for a nice explanation
看到这里一个很好的解释
In a nutshell, let's say your argument that you are passing is this 简而言之,假设您要传递的论点是这样的
param = {'a': 2, 'b': 3}
Now if we: 现在,如果我们:
temp = param
print temp # {'a': 2, 'b': 3}
And we change the value of temp
: 然后我们更改
temp
的值:
temp['a'] = 8
Now we check param
again and: 现在,我们再次检查
param
并:
print param
{'a': 8, 'b': 3}
As with your problem, param changes even when we copy it to a temp variable and change the temp. 与您的问题一样,即使我们将参数复制到temp变量并更改温度,参数也会更改。
From the Python Data model 从Python数据模型
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.
例如,数字,字符串和元组是不可变的,而字典和列表则是可变的。
So you are making both your variables point to the same object - and when it's changed, both change as they are pointing to the same thing. 因此,您要使两个变量都指向同一个对象-更改对象时,它们都将指向同一对象而更改。 If you want to make a copy to work on of a dict, for example, try
例如,如果要复制副本以处理字典,请尝试
dict2 = dict(dict1)
Or also dict2 = dict1.copy()
或者也
dict2 = dict1.copy()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.