Python 中的函数将列表视为全局变量.如何解决这个问题?



我不确定为什么l会被find()函数修改。我认为由于我在另一个函数中使用不同的变量,l不会被该函数修改,因为它不是全局的。

我通过在每次打印语句之前复制和粘贴l = [2, 4, 6, 8, 10]来确保它不是代码中的错误,并且它返回了正确的输出,这意味着函数正在更改l。我还从 main 中删除了 main 函数,基本上让它完全全局化,但它仍然给出了原来的糟糕结果。

我不确定这是否是我对Python的理解问题,因为我是它的初学者,而且我来自Java。

下面是代码和结果:

def find(list, user):
while True:
n = len(list)
half = int(n/2)
if n == 1:
if user != list[0]:
return "Bad"
else:
return "Good"
elif user == list[half]:
return "Good"
elif user > list[half]:
del list[0:half]
elif user < list[half]:
del list[half:n]
print(list)
if __name__ == "__main__":
l = [2, 4, 6, 8, 10]
print(find(l, 5))  # should print Bad
print(find(l, 10))  # should print Good
print(find(l, -1))  # should print Bad
print(find(l, 2))  # should print Good

但它带着这个返回

[2, 4]
[4]
Bad
Bad
Bad
Bad

你应该首先阅读这个问题。 为什么函数可以修改某些参数而不能修改其他参数。

让我重写您的代码以澄清。

def find(li, el):
# li is a list, el is an integer
# do something using li and el
if __name__ == "__main__":
l = [1,2,3,4]
e = 2
find(l, e)    

该函数find接收两个对象作为参数,一个是li,另一个是el。在main中,我们定义了两个对象,一个列表,我们称之为l,和一个整数,我们称之为e。然后将这两个对象传递给find.应该清楚的是,传递给函数的是这两个对象,而不是名称。然后,您的find函数可以访问此对象,在main中称为l,而在find中称为li。所以当你在find中改变li时,l也会改变。

希望能回答你的问题。要解决此问题,请检查deepcopy.

Python 中的参数是通过赋值传递的。 https://docs.python.org/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference

在您的情况下,这意味着find函数的list参数被分配与您传入的参数完全相同的列表l.因此,当您修改list(这是一个非常糟糕的名称,因为它隐藏了 Python 的list关键字(时,您也修改了l,因为没有制作原件的副本。

您可以使用copy()传入副本,但我认为您最好重新考虑整个函数,因为它目前有很多很多问题,并且您最终可能会得到一个不会受到影响的解决方案传递原始列表。

最新更新