上下文:我需要随机删除一些数字列表中的一些精确元素,提取一些随机索引并将它们保存在一个名为 aleaindex 的集合中(完成后,它正确的工作,感谢一些SO用户的帮助)。现在,我想将旧的列表 a , b 等替换为新的,最终更短的 newa , newb 等。这是功能:
def myfunction(N, other_parameters, a, b, c):
...
while (...):
aleaindex.add(random.randint(..., ...))
...
new_a = [v for i, v in enumerate(a) if i not in aleaindex]
while a: a.pop()
a = new_a[:]
...
依此类推其他列表 b , c 等。
问题:该函数似乎在模块中正确修改它们(通过打印检查)但是,当我打印修改后的列表在模块外面时,就是“主”文件,列表是他们没有修改过的。我哪里错了?
答案 0 :(得分:8)
这一行:
a=new_a[:]
用新对象覆盖变量a
。在函数或模块之外,a
(或者在那里调用的任何东西)仍指向旧对象。尝试:
new_a = [v for i, v in enumerate(a) if i not in aleaindex]
while a:
a.pop()
a[:] = new_a[:]
要查看此内容,请尝试以下操作。
>>> a = [1,2,3,4]
>>> b = a
>>> print b
[1, 2, 3, 4]
>>> a[:] = [2,3]
>>> print b
[2, 3]
>>> a = [5]
>>> print b
[2, 3]
如果变量是可变的(并且正常列表是),则可以:
>>> def f(a):
... a[0] = 2
>>> b = [3]
>>> f(b)
>>> print b
[2]
变量不按值传递 - 您可以编辑可变值。
答案 1 :(得分:2)
我不知道你想要做什么但是从你的片段中你显然已经失去了。您的代码没有多大意义,并且存在多个问题。尽管如此,你问的问题是 - 为什么列表没有完全改变? - 似乎与这个循环有关:</ p>
while a: a.pop()
a = new_a[:]
假设我们以这种方式调用你的函数:
list1 = [1, 2, 3, 4, 5, 6, 7]
myfunction(N, other_parameters, list1, [], [])
当您拨打第一行时,您将获得一个名为list1
的变量,它将指向一个列表:
当您调用函数myfunction()
时,该函数除其他外,还会创建一个名为a
的变量,该变量将指向list1
指向的相同列表:
到目前为止,这么好。然后我们进入下面的循环:
while a:
a.pop()
a = new_a[:]
在第一行(a.pop()
)中,您可以从列表中获取一个项目。由于变量a
和list1
都指向同一个列表,因此您会看到相同的结果......
...如果不是循环的下一行(a = new_a[:]
)。在这一行中,您将a
变量指向另一个列表:
现在,您在a
上执行的每项操作都将出现在此列表中,该列表与list1
无关。例如,您可以在下一次迭代中执行a.pop()
来获取它:
然而,它完全没有意义,因为行a = new_a[:]
将替换再次指向的列表 另一个不同的列表 >:
那么,解决方案是什么?我不知道。正如我所说的那样,(至少对我来说)不可能从你的代码中理解。你必须更多地反思你正在尝试做什么,并向我们解释一下,还有更多的背景。
答案 2 :(得分:1)
您发布的代码中没有任何功能。我怀疑问题是你没有返回新值。
您的代码可能会执行以下操作:
a = "foo"
def func():
a = "bar" # uh-oh this not the same as the global a
func()
此时全局a
未更改,因为a
func
的本地变量不同。
你想这样做:
a = "foo"
def func():
return "bar"
a = func()
该代码在全局范围内分配给a
,并进行更改。