【问题标题】:Local and Global lists in PythonPython 中的本地和全局列表
【发布时间】:2019-02-12 08:25:03
【问题描述】:

请帮助我,因为我是 python 新手 当我调用这个函数时,list1 的原始值发生了变化

def mystery(list1):
  list1[0] , list1[1] = list1[1], list1[0]

list1 = [7,82,44,23,11]
mystery(list1)
print(list1) #prints [82, 7, 44, 23, 11]

它如何改变全局list1 的值 如果我将我的功能更改为

def mystery(list1):
  list1 = list1 + list1[2:5]

然后我得到list1 的全局值,而不是更新后的值。

【问题讨论】:

  • 在函数末尾使用return 将更新后的值传回给调用者怎么样?
  • 是的,但是我对 python 中的局部变量和全局变量感到困惑,这里在第一个函数中 list1 的值被更改为新的 list1 而没有返回。但在第二个函数中它保持不变。
  • list1 = list1 + list1[2:5] 创建一个新的列表对象list1,其可见性仅在函数内。当您在外部引用list1 时,您访问的是旧的list1。在这里,list1[0] , list1[1] = list1[1], list1[0],更新了相同的列表对象,这就是为什么您会在输出中看到更新的值。
  • 谢谢,@Austin 我明白了。

标签: python python-3.x list global-variables local-variables


【解决方案1】:

list1 发生变化的原因是因为您实际上是在修改函数内部的列表对象。

它实际上与全局/局部变量无关,如果您将函数内的参数重命名为其他参数,并且仍然传入 list1,则 list1 将被修改。

如果您想返回一个新列表,您需要先创建一个列表的副本,有很多方法可以做到这一点。 list(list1) 是一种方式。然后return函数末尾的列表。

如果我理解您的问题,您实际上想在传入的列表中添加更多值,请使用 list1.append(...) 添加到列表的末尾。

而且由于您正在修改列表本身,它会在更大的范围内发生变化。

但它仍然没有使用全局作用域,因为您只是在本地作用域中使用了同名的 var。

【讨论】:

    【解决方案2】:

    也许只是返回列表?

    def mystery(list1):
        return list1 + list1[2:5]
    
    list1 = [7,82,44,23,11]
    list1 = mystery(list1)
    print(list1)
    

    【讨论】:

      【解决方案3】:

      列表是 Python 中的可变对象,因此如果您将一个列表传递给一个函数,那么您对函数内部列表所做的所有更改都将反映在任何地方/全局上

      如果你将一个可变对象传递给一个方法,该方法会获得一个对同一个对象的引用,你可以随心所欲地改变它,但是如果你在方法中重新绑定引用,外部作用域将对此一无所知,完成后,外部引用仍将指向原始对象。

      如果将不可变对象传递给方法,仍然无法重新绑定外部引用,甚至无法改变对象。[more details here]

      【讨论】:

      • 谢谢,@rusu_ro1 我明白了。
      【解决方案4】:

      在 python 中,将值分配给像a = 5 这样的变量意味着您正在内存中为值 5 创建一个对象。现在a 是指向该对象的链接 5(用外行的话来说)。如果你现在更改a,比如a = "something else",这会在内存中的其他地方为字符串"something else" 创建一个新对象,现在a 指向它。这就是为什么你可以改变 python 变量的数据类型。

      当您将某些内容传递给 python 函数时,该链接就是被传递的链接。因此,当您调用mystery(list1) 时,会传递指向list1 的原始链接。因此,更改list1 中的元素意味着您正在为原始list1 中的特定元素分配一个新值。在这种情况下,无论您是在函数 mystery() 的内部还是外部,因为您将使用您创建的原始链接来访问 list1 内部的元素来更改它。更改发生在list1 内部; list1 没有被重新分配。

      但是,当您在函数 mystery() 中执行 list1 = "something new" 时,您将在函数内部创建一个新变量 list1,该变量是函数的本地变量。你并没有改变原来的list1

      【讨论】:

        【解决方案5】:

        将可变对象传递给函数,然后在函数内部修改对象,与直接修改对象的效果是一样的。

        list1 = [1,2,3]
        
        def func(list1):
            list1[0] = 5
        
        >>>list1
        [5,2,3]
        

        这实际上与直接运行 list1[0] = 5 相同

        但是,如果将不可变对象传递给元组等函数,它将不支持项目分配TypeError: 'tuple' object does not support item assignment。所以你需要构建一个新的不可变对象并返回它。

        >>> tup1 = (1,2,3) # doing tup1[0] = 5 will cause TypeError
        >>> tup2 = tup1 + (5,)
        >>> tup2
        (1, 2, 3, 5)
        

        把它放在函数中,

        >>> def func2(tup1):
                return tup1 + (5,)
        
        >>> func2(tup1=(1,2,3))
        (1, 2, 3, 5)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-11-15
          • 1970-01-01
          • 1970-01-01
          • 2014-03-19
          • 1970-01-01
          • 1970-01-01
          • 2023-03-03
          相关资源
          最近更新 更多