这个问题很容易理解,下面是程序——
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 会改变?我怎样才能阻止它改变?抱歉,如果这是显而易见的事情。
这个问题很容易理解,下面是程序——
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 会改变?我怎样才能阻止它改变?抱歉,如果这是显而易见的事情。
Python 变量是引用。因此,赋值复制了引用而不是变量的内容。
为了避免这种情况,您所要做的就是创建一个新对象:
ohisc = list(hisc)
这是使用list
构造函数从给定的迭代创建一个新列表。
或者,您也可以从切片分配(创建一个新对象):
ohisc = hisc[:]
[]
是通用切片运算符,用于从给定集合中提取子集。我们只是省略了开始和结束位置(它们分别默认为集合的开始和结束)。
您绝对需要了解康拉德鲁道夫答案中的所有内容。我认为在你的具体情况下,这也是你想要的。但通常有更好的方法:如果您避免改变对象(即,就地更改它们),那么两个名称是否引用同一个对象都无关紧要。例如,您可以更改:
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]
那么,你什么时候想要变异?嗯,通常你想要两个对同一个对象的引用,所以当你更新一个时,另一个会看到变化。在这种情况下,您显然必须进行实际更改才能让其他人看到。
这是对正在发生的事情的一个很好的解释:Python:以正确的方式复制列表
基本上,您正在创建一个指向列表的指针,但您想要做的是制作列表的副本。
试试这个:
hisc = [1,2,3,4]
ohisc = hisc[:]