【问题标题】:Function in Python is treating list like a global variable. How to fix this?Python 中的函数将列表视为全局变量。如何解决这个问题?
【发布时间】:2020-04-21 17:06:03
【问题描述】:

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

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

我不确定这是否与我对 Python 的理解有关,因为我是 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

【问题讨论】:

  • del ... 正在修改原始列表,因为您传入的不是列表的副本,而是对原始列表本身的引用。最简单的解决方法是传入列表的副本:find(l[:], 5)
  • 为什么在find() 中使用print(list)?不应该是return text
  • 您应该采用基于索引的方法,而不是使用del
  • 变量list只是对原始列表l的引用。因此,当您修改变量list 时,原始列表也会被修改。另外请避免使用list 作为变量名,因为它们是python 中的关键字。如果您想修改列表,只需复制一份即可。

标签: python search binary global


【解决方案1】:

您应该首先阅读这个问题。 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。因此,当您将 li 更改为 find 时,l 也会更改。

希望能回答您的问题。要解决此问题,请查看deepcopy

【讨论】:

    【解决方案2】:

    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() 传递一个副本,但我认为您最好重新考虑整个函数,因为它目前有很多很多问题,您最终可能会得到一个解决方案不会因为传入原始列表而受到影响。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      • 2021-10-14
      • 2019-02-08
      • 2016-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多