在python中重新分配变量

在python中重新分配变量,python,Python,我有以下代码和变量,我想找出执行代码后变量a、a1、a2、b、b1和b2所指的内容 def do_something(a, b): a.insert(0, "z") b = ["z"] + b a = ["a", "b", "c"] a1 = a a2 = a[:] b = ["a", "b", "c"] b1 = b b2 = b[:] do_something(a, b) 我尝试的解决方案如下: a = ["z", "a", "b", "c"] a1 = ["a", "

我有以下代码和变量,我想找出执行代码后变量
a
a1
a2
b
b1
b2
所指的内容

def do_something(a, b):
    a.insert(0, "z")
    b = ["z"] + b

a = ["a", "b", "c"]
a1 = a
a2 = a[:]
b = ["a", "b", "c"]
b1 = b
b2 = b[:]

do_something(a, b)
我尝试的解决方案如下:

a = ["z", "a", "b", "c"]
a1 = ["a", "b", "c"]
a2 = ["a", "b", "c"]
b = ["z" "a", "b", "c"]
b1 = ["a", "b", "c"]
b2 = ["a", "b", "c"]
但实际的解决办法是:

a = ["z", "a", "b", "c"]
a1 = ["z", "a", "b", "c"]
a2 = ["a", "b", "c"]
b = ["a", "b", "c"]
b1 = ["a", "b", "c"]
b2 = ["a", "b", "c"]

有人能告诉我我的错误吗?

好的,你可以把Python中的变量当作引用。当您这样做时:

a1 = a
a2 = a[:]
b = ['z'] + b
a1
a
都是对同一对象的引用,因此如果修改
a
指向的对象,您将看到
a1
中的更改,因为-出乎意料-它们是同一个对象(并且
list.insert
方法会在适当的位置修改列表)

但当你这样做的时候:

a1 = a
a2 = a[:]
b = ['z'] + b
然后,
a2
是一个新的
列表
实例,当您修改
a
时,您没有修改
a2

列表的
+
运算符的结果是一个新列表,因此执行此操作时:

a1 = a
a2 = a[:]
b = ['z'] + b
您正在为
b
分配一个新列表,而不是像对待
b那样对
b
进行适当的变异。插入('z')
。现在
b
指向一个新对象,而
b1
仍然指向
b
的旧值

但作用域可能更复杂:您可以从函数中看到封闭作用域,但如果在函数中指定变量,则不会更改封闭(或全局或内置)作用域中同名的变量,而是会在局部作用域中创建同名的变量。这就是为什么b没有被改变的原因——好吧,不完全是这样,Python中的参数传递是一个赋值操作,所以当有一个名为
b
的参数时,
b
已经是一个局部变量了——但是试图改变封闭范围中定义的变量会导致类似的问题。顺便说一句,依赖封闭作用域中的变量是一种不好的做法,除非它们是模块级常量(传统上它们是以全大写形式命名的,并且不应该对它们进行变异)。如果需要函数内的值,请将其作为参数传递,如果要更改封闭范围内变量的值,请返回该值并在其中指定返回值:

def do_something(a, b):
    a.insert(0, "z")  # mutates a in-place
    return ["z"] + b

b = do_something(a, b)

您在什么时候找到/打印出所有变量的值?也许这与范围有关,我认为“我尝试的解决方案”是指“我期望的”。。。对吗?这可能会消除一些混淆。阅读可能有助于理解为什么会发生这种情况。在
do\u something
中值得一提的
b
已在本地重新分配,因此不会更改全局
b
值。在
do\u something()中计算的
b
是函数的本地属性,当函数结束时会被丢弃。函数未触及全局变量
b
b1
b2
。谢谢各位,祝你们好运。