Python 中的函数将列表视为全局变量。如何解决这个问题?
Function in Python is treating list like a global variable. How to fix this?
我不确定为什么 l
会被 find()
函数修改。我想因为我在另一个函数中使用了不同的变量,所以 l
不会被函数修改,因为它不是全局的。
我通过在每个 print 语句之前复制和粘贴 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
但是 returns 和这个
[2, 4]
[4]
Bad
Bad
Bad
Bad
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()
传递一个副本,但我认为您最好重新考虑整个功能,因为它目前有很多很多问题,您可能最终会使用不会因传入原始列表而受到影响的解决方案。
你应该首先阅读这个问题。 why can a function modified some arguments while not others.
让我重写您的代码以进行说明。
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
.
我不确定为什么 l
会被 find()
函数修改。我想因为我在另一个函数中使用了不同的变量,所以 l
不会被函数修改,因为它不是全局的。
我通过在每个 print 语句之前复制和粘贴 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
但是 returns 和这个
[2, 4]
[4]
Bad
Bad
Bad
Bad
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()
传递一个副本,但我认为您最好重新考虑整个功能,因为它目前有很多很多问题,您可能最终会使用不会因传入原始列表而受到影响的解决方案。
你应该首先阅读这个问题。 why can a function modified some arguments while not others.
让我重写您的代码以进行说明。
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
.