Python中的列表、变量赋值和函数

时间:2021-07-07 23:25:33

I have the following code:

我有以下代码:

def proc2(p):
    p=p+[1]
y=[2,5]
proc2(y)
print(y)


z=[2,5]
z=z+[1]
print(z)

The output of the code is:

代码输出为:

[2, 5]
[2, 5, 1]

I understand that y is not modified to [2,5,1]. But, y is reassigned to a new list, which is [2,5,1], right? Then why does y still refer to the original value? If the value of z has changed, why not y?

我知道y没有被修改为[2,5,1]。但是,y被重新分配到一个新的列表,它是[2,5,1],对吧?那么为什么y仍然指向原始值呢?如果z的值变了,为什么y不变呢?

P.S. I have just asked a question which is almost the same as this one. That question has been marked as a duplicate of another question. However, I think they are a bit different. That is why I'm posting my question again. I think I must have missed something about function.

附注:我刚才问了一个和这个问题差不多的问题。那个问题被标记为另一个问题的重复。然而,我认为他们有点不同。这就是为什么我要再次提出我的问题。我想我一定是漏掉了函数。

4 个解决方案

#1


0  

y is reassigned to a new list

y被重新分配到一个新的列表

No, there's only one y = ... assignment in your code.

不,只有一个y =…代码中的分配。

What happens when your function executes is the following:

当您的函数执行时,会发生以下情况:

# implicitly: assign formal parameter name to actual argument value
p = y

# compute p + [1] => [2, 5, 1]
# assign the result to the name p
p = p + [1]

# aaaand... nothing from here on.

So your function computes a result (a new list), assigns the name p inside the function scope, and then p is lost as soon as the function exits.

因此,函数计算一个结果(一个新列表),在函数范围内分配名称p,然后函数一退出就丢失p。

If you don't want to write a function that mutates your input list, you need to return the computed value and re-assign the name y to see the desired effect.

如果您不想编写一个改变输入列表的函数,您需要返回计算值并重新分配名称y以查看所需的效果。

>>> def proc2(p):
...     p = p + [1]
...     return p
... 
>>> y = [2,5]
>>> y = proc2(y)
>>> y
[2, 5, 1]

Note that even if you had an y = ... assignment inside your function, that name would be local to the function and the outer scope would not care:

注意,即使你有一个y =…在函数内部的赋值,该名称将是函数的本地名称,而外部范围将不关心:

>>> def proc2(y):
...     y = y + [1]
... 
>>> y = [2,5]
>>> proc2(y)
>>> y
[2, 5]

Finally, you could tell Python that you mean the global y inside your functions body, but that's considered poor style (definitely here and in most other cases).

最后,您可以告诉Python您是指函数体中的全局y,但这被认为是糟糕的样式(在这里和大多数其他情况下都是如此)。

>>> def proc2():
...     global y
...     y = y + [1]
... 
>>> y = [2,5]
>>> proc2()
>>> y
[2, 5, 1]

#2


0  

Your variable y is not changed because you change the variable p, which is local to your function. This variable has nothing to do with y after the function ends.

变量y没有改变,因为你改变了变量p,它是函数的局部。这个变量与函数结束后的y无关。

#3


0  

Two options:

两个选择:

  1. Either have your function return the new list:

    或者让你的函数返回新的列表:

    def proc2(p):
        return p + [1]
    
  2. Or, have it modify the p in-place (and optionally return it for cleaner coding):

    或者,让它在适当的位置修改p(并可以选择返回它以进行更清晰的编码):

    def proc2(p):
        p += [1]  # this is not exactly the same as p = p + [1]
        return p  # <- optional!
    

Your code, instead of modifying the existing p, it creates a new one which is however not communicated to the outer scope; and as a result dies when the function quits.

您的代码没有修改现有的p,而是创建了一个新的p,但是没有与外部范围通信;当函数退出时,结果就会消失。

#4


0  

To better understand what happens here, check ids of z and y, they are different, which means z and y are different objects. Changing one of them does not affect the other.

为了更好地理解这里发生了什么,检查z和y的id,它们是不同的,这意味着z和y是不同的对象。改变其中一个并不影响另一个。

y=[1,2] z=[1,2] print id(y), id(z)

y=[1,2] z=[1,2]打印id(y) id(z)

#1


0  

y is reassigned to a new list

y被重新分配到一个新的列表

No, there's only one y = ... assignment in your code.

不,只有一个y =…代码中的分配。

What happens when your function executes is the following:

当您的函数执行时,会发生以下情况:

# implicitly: assign formal parameter name to actual argument value
p = y

# compute p + [1] => [2, 5, 1]
# assign the result to the name p
p = p + [1]

# aaaand... nothing from here on.

So your function computes a result (a new list), assigns the name p inside the function scope, and then p is lost as soon as the function exits.

因此,函数计算一个结果(一个新列表),在函数范围内分配名称p,然后函数一退出就丢失p。

If you don't want to write a function that mutates your input list, you need to return the computed value and re-assign the name y to see the desired effect.

如果您不想编写一个改变输入列表的函数,您需要返回计算值并重新分配名称y以查看所需的效果。

>>> def proc2(p):
...     p = p + [1]
...     return p
... 
>>> y = [2,5]
>>> y = proc2(y)
>>> y
[2, 5, 1]

Note that even if you had an y = ... assignment inside your function, that name would be local to the function and the outer scope would not care:

注意,即使你有一个y =…在函数内部的赋值,该名称将是函数的本地名称,而外部范围将不关心:

>>> def proc2(y):
...     y = y + [1]
... 
>>> y = [2,5]
>>> proc2(y)
>>> y
[2, 5]

Finally, you could tell Python that you mean the global y inside your functions body, but that's considered poor style (definitely here and in most other cases).

最后,您可以告诉Python您是指函数体中的全局y,但这被认为是糟糕的样式(在这里和大多数其他情况下都是如此)。

>>> def proc2():
...     global y
...     y = y + [1]
... 
>>> y = [2,5]
>>> proc2()
>>> y
[2, 5, 1]

#2


0  

Your variable y is not changed because you change the variable p, which is local to your function. This variable has nothing to do with y after the function ends.

变量y没有改变,因为你改变了变量p,它是函数的局部。这个变量与函数结束后的y无关。

#3


0  

Two options:

两个选择:

  1. Either have your function return the new list:

    或者让你的函数返回新的列表:

    def proc2(p):
        return p + [1]
    
  2. Or, have it modify the p in-place (and optionally return it for cleaner coding):

    或者,让它在适当的位置修改p(并可以选择返回它以进行更清晰的编码):

    def proc2(p):
        p += [1]  # this is not exactly the same as p = p + [1]
        return p  # <- optional!
    

Your code, instead of modifying the existing p, it creates a new one which is however not communicated to the outer scope; and as a result dies when the function quits.

您的代码没有修改现有的p,而是创建了一个新的p,但是没有与外部范围通信;当函数退出时,结果就会消失。

#4


0  

To better understand what happens here, check ids of z and y, they are different, which means z and y are different objects. Changing one of them does not affect the other.

为了更好地理解这里发生了什么,检查z和y的id,它们是不同的,这意味着z和y是不同的对象。改变其中一个并不影响另一个。

y=[1,2] z=[1,2] print id(y), id(z)

y=[1,2] z=[1,2]打印id(y) id(z)