这个问题很容易理解,这是程序 -
hisc = [1,2,3,4]
print("\n", hisc)
ohisc = hisc
hisc.append(5)
print("\nPreviously...", ohisc)
print("\nAnd now...", hisc)
input("\nETE")
当我运行时,ohisc得到5.为什么ohisc会改变?如何阻止它改变? 如果这是明显的事情,请道歉。
答案 0 :(得分:5)
Python variables are references。因此,赋值会复制引用而不是变量的内容。
为了避免这种情况,您所要做的就是创建一个 new 对象:
ohisc = list(hisc)
这是使用list
constructor,它从给定的可迭代创建一个新列表。
或者,您也可以从切片(创建新对象)进行分配:
ohisc = hisc[:]
[]
是general slice operator,用于从给定集合中提取子集。我们简单地省略了开始和结束位置(它们分别默认为集合的开头和结尾)。
答案 1 :(得分:2)
你肯定需要了解Konrad Rudolph的答案中的所有内容。我认为在你的具体情况下,这也是你想要的。但通常有更好的方法:如果你避免变异对象(即,就地更改它们),那么两个名称是否指向同一个对象永远不会重要。例如,您可以更改此内容:
hisc.append(5)
到此:
hisc = hisc + [5]
这不会就地改变hisc
;它会创建一个新的list
,并在其末尾添加5
,然后将其分配给hisc
。因此,ohisc
指向与list
相同的hisc
这一事实并不重要 - list
仍未存在,ohisc
指向。
假设你想用0替换列表中的所有负值。这很容易变异:
for i in range(len(lst)):
list[i] = max(list[i], 0)
但没有更容易:
lst = [max(elem, 0) for elem in lst]
现在,如果你想删除每个否定列表元素怎么办?循环时序列的形状不能更改,因此您必须复制列表(这样您可以在更改另一个时循环复制一个副本),或者提出更复杂的算法(例如,向后交换每个0然后在结尾处移除所有0)。但这很容易做到不可变:
lst = [elem for elem in lst if elem >= 0]
那么,你什么时候想变异?好吧,通常你想要对同一个对象进行两次引用,所以当你更新一个时,另一个看到了这些变化。在这种情况下,您显然必须对另一个进行实际更改才能看到。
答案 2 :(得分:1)
这里有一个很好的解释:Python: copying a list the right way
基本上,你正在制作一个指向列表的指针,但你要做的是复制一份列表。
请改为尝试:
hisc = [1,2,3,4]
ohisc = hisc[:]