【问题标题】:Python global list modification inside and outside of functions函数内外的Python全局列表修改
【发布时间】:2014-06-19 14:59:31
【问题描述】:

2我对 Python 比较陌生(使用 3.3.3)并且有一个与列表相关的问题。在函数内部修改全局列表变量时(请不要讲全局变量的坏处),通常不需要在函数内部使用 global 关键字声明列表 - 只要您坚持使用列表方法。特别是,如果不先使用 global 关键字,则不能使用增广加法。令我惊讶的是,在函数外部使用增广加法显然不会修改列表变量(仅列表内容),因此我希望可以在不使用 global 关键字的情况下在函数内部使用它。这是我无法协调的两个例子:

list_1 = []

def my_func():
    list_1.append(0)
    #list_1 += [0]

my_func()
print('list_1 =', list_1)

正如预期的那样,这将打印list_1 = [0],而注释掉的增强加法操作会产生关于在赋值之前使用局部变量的抱怨。

这是一个我无法与上一个调和的例子:

list_1 = [0]
list_2 = list_1
list_1 += [1]
print('list_2 =', list_2)

这会打印出list_2 = [0, 1],这表明list_1 += [1] 没有修改list_1 变量。我知道list_1 = list[1] + [1] 有资格修改list_1,但增加的添加似乎没有。为什么在函数内部的增广加法需要使用 global 关键字?感谢您对理解这一点的任何帮助。

【问题讨论】:

  • 您是否尝试打印出list_1 以检查您的假设list_1 += [1] 没有修改list_1
  • 您说“这打印出list_2 = [0, 1],这表明list_1 += [1] 没有修改list_1 变量。”为什么这会提示你?
  • @BrenBarn 我相信 Jon 的意思是 list_1 += [1] 不会导致 list_1 指向不同的列表,而 list_1 = list_1 + [1] 创建一个新列表并让 list_1 指向该新列表。
  • @Rob Watts 是的,这正是我的意思。

标签: python


【解决方案1】:

问题是,当解析函数体时,在正常赋值或扩充赋值中使用的所有变量都被视为局部变量,因此当函数被调用时,Python 不会在全局范围内查找这些变量,因此它会引发错误。因此,您需要将这些变量指定为 global 以告诉 Python 在全局范围内查找它们。

另一种选择是使用list.extend() 而不是+=

相关:

【讨论】:

  • 我会说这是一个可读性和一致性的问题。如果list_1 是一个int,+= 将重新分配,因此必须使用global 是有意义的。 += 将对所有类型的全局性产生相同的影响是有道理的
  • 仅供参考,OP 询问了 Python 3.x,但您的第一个链接是 Python 2.x 文档。
  • @njzk2 如果我的观点正确,那么对于不可变类型,您使用+= 还是普通= 都没有关系,因为无论如何它只会更新一个变量和所有其他参考将不受影响。因此,+= 将根据对象的类型产生不同的效果。
  • @RobWatts 更新了链接,除了nonlocal 部分它们基本相同。
  • @Aशwiniचhaudhary:是的。如果您查看 a = 3; id(a); a += 1; id(a)lst = []; id(lst); lst += [0]; id(lst),您会看到 += 重新分配不可变类型(显然必须)但没有重新分配列表。
猜你喜欢
  • 2015-10-04
  • 1970-01-01
  • 2015-01-31
  • 2014-03-30
  • 1970-01-01
  • 2015-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多