Python - 一个变量不应该等于另一个变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/264575/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python - one variable equals another variable when it shouldn't
提问by darudude
Here is my sample code. It is meant to be an iterative procedure for gauss seidel (matrix solver). Essentially when the error is small enough it breaks out of the while loop.
这是我的示例代码。它旨在成为高斯赛德尔(矩阵求解器)的迭代过程。本质上,当错误足够小时,它会跳出 while 循环。
i=1
while (i>0):
x_past = x_present
j=0
while(j<3):
value=0
k=0
while(k<3):
if(k!=j):
if(i==1):
if(k>j):
value=value+0
else:
value=value+x_present[k]*eqn[j][k]
else:
value=value+x_present[k]*eqn[j][k]
else:
value=value+eqn[j][k]
k=k+1
x_present[j:j+1]=[value]
j=j+1
print "X_PAST"
print x_past
print "X_PRESENT"
print x_present
if(error(x_past, x_present)<10**-2):
break;
i=i+1
I've reduced the code so its more manageable. if you don't understand what its doing its not really that important to solving this problem.
我减少了代码,使其更易于管理。如果你不明白它在做什么,那么解决这个问题就不是那么重要了。
Here is the issue. Everytime
这是问题。每次
x_present[j:j+1]=[value]
is run, x_past is made equal to x_present. I don't know why this is the case as the only place i have set x_past equal to x_present is at the top of the loop. If I take away the
运行时,x_past 等于 x_present。我不知道为什么会这样,因为我将 x_past 设置为 x_present 的唯一位置是在循环的顶部。如果我带走
x_past=x_present
sentence, x_past is never made equal to x_present. This leads me to think it is some combination of the two statements that is causing the issue.
句子中,x_past 永远不会等于 x_present。这让我认为是导致问题的两个陈述的某种组合。
This is a big problem cause if x_past = x_present the error = 0 every time and the loop breaks after the first iteration. The code does work, for example if I tell the code to run for 8 iterations and the break it gives me the answer its supposed to.
如果每次 x_past = x_present 错误 = 0 并且循环在第一次迭代后中断,这是一个大问题。代码确实有效,例如,如果我告诉代码运行 8 次迭代,并且中断它给了我应该的答案。
I've been trying to figure this out for the last 4 hours and am completely stumped. I haven't been working with python long, so my trouble shooting skills syntax wise aren't that great. Any help would be appreciated!!
在过去的 4 个小时里,我一直在努力解决这个问题,但我完全被难住了。我没有长时间使用 python,所以我在语法方面的故障排除技巧并不是那么好。任何帮助,将不胜感激!!
回答by monkut
Yes, I think the answers here show your problem. Just to try and clarify a little bit.
是的,我认为这里的答案显示了您的问题。只是想尝试澄清一点。
You're referencing a list, so when the list changes any reference to that list will reflect that change. To demonstrate:
您正在引用一个列表,因此当列表更改时,对该列表的任何引用都将反映该更改。展示:
>>> x_present = [4,5,6]
>>>
>>> x_past = x_present
>>>
>>> x_past
[4, 5, 6]
>>>
>>> x_present.append(7)
>>>
>>> x_past
[4, 5, 6, 7]
>>>
If you want a copy of the list you have to do do this, listcopy = mylist[:].
如果你想要一份列表的副本,你必须这样做,listcopy = mylist[:]。
>>> x_past = x_present[:]
>>> x_past
[4, 5, 6, 7]
>>>
>>> x_present.append(8)
>>>
>>> x_past
[4, 5, 6, 7]
回答by Jon Skeet
What are x_past and x_present? I don't know much Python, but from a .NET/Java perspective, if they're references to some data structure (a map or whatever) then making them references to the same object (as you do at the start) will mean that any changes made through one variable will be visible through the other. It sounds like you need to take a copy of the data structure instead of just doing a reference assignment. Does the data structure you're working with have any kind of "clone" functionality available?
什么是 x_past 和 x_present?我对 Python 了解不多,但从 .NET/Java 的角度来看,如果它们是对某些数据结构(地图或其他任何东西)的引用,那么将它们引用到同一个对象(就像您在开始时所做的那样)将意味着通过一个变量所做的任何更改都将通过另一个变量可见。听起来您需要获取数据结构的副本,而不仅仅是进行引用分配。您正在使用的数据结构是否具有任何类型的“克隆”功能?
As I say though, I don't know much Python so this could be totally wrong...
正如我所说,我对 Python 了解不多,所以这可能是完全错误的......
回答by jfs
As others pointed out the answer is to replace: x_past = x_present
by x_past = x_present[:]
. In general you could use a copy
module to copy an object in Python.
正如其他人指出的那样,答案是替换:x_past = x_present
by x_past = x_present[:]
。通常,您可以使用copy
模块在 Python 中复制对象。
>>> import copy
>>> a = range(10)
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> b = a
>>> a += 10, 11
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
>>> b
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
>>> c = copy.copy(a) # shallow copy
>>> c
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
>>> del a[3:]
>>> a
[0, 1, 2]
>>> b
[0, 1, 2]
>>> c
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Your code is unpythonic to say the least.
至少可以说,您的代码是 unpythonic。
It could be replaced by something like the following code:
它可以替换为类似以下代码的内容:
import copy
# assert(len(x_present) >= len(eqn))
first = True
while True:
x_past = copy.copy(x_present) # copy
for j, eqj in enumerate(eqn):
x_present[j] = sum(x_present[k] * eqj[k]
for k in range(j if first else len(eqj))
if k != j)
x_present[j] += eqj[j]
print "X_PAST\n%s\nX_PRESENT\n%s" % (x_past, x_present)
if allequal(x_past, x_present, tolerance=10**-2):
break
first = False
Here's a definition of allequal()
(using an absolute error. It might or might not be a good idea in your case (you could use a relative error instead)):
这是allequal()
(使用绝对错误。在您的情况下它可能是也可能不是一个好主意(您可以使用相对错误代替))的定义:
def allequal(x, y, tolerance):
return (len(x) == len(y) and
all(-tolerance < (xx - yy) < tolerance
for xx, yy in zip(x, y)))
回答by eddy147
In Python, everything is an object. So the statement x_past = x_present point to the same reference.
在 Python 中,一切都是对象。所以语句 x_past = x_present 指向同一个引用。
回答by unwind
It looks as if x_present is a list. I suspect that this means that the assignment x_last = x_present makes x_last into an alias, i.e. they reference the same variable. Might this be the case?
看起来好像 x_present 是一个列表。我怀疑这意味着赋值 x_last = x_present 使 x_last 成为别名,即它们引用相同的变量。可能是这种情况吗?
回答by Lukman
try changing the x_past = x_present
line to x_past = [x for x in x_present]
and see if it helps.
尝试将x_past = x_present
行更改为x_past = [x for x in x_present]
,看看是否有帮助。
the list copy shorthand is my favorite python feature since i can do one-liners that are not possible in other languages:
list copy 速记是我最喜欢的 Python 特性,因为我可以做其他语言无法做到的单行:
greaterthan100 = [x for x in number if x > 100]
greaterthan100 = [x for x in number if x > 100]
notinblacklist = [x for x in mylist if x not in blacklist]
notinblacklist = [x for x in mylist if x not in blacklist]
firstchildofbigfamily = [x.child[0] for x in familylist if len(x.child) > 10]
firstchildofbigfamily = [x.child[0] for x in familylist if len(x.child) > 10]