Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中的列表、变量赋值和函数_Python_Python 3.x - Fatal编程技术网

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

Python中的列表、变量赋值和函数,python,python-3.x,Python,Python 3.x,我有以下代码: def proc2(p): p=p+[1] y=[2,5] proc2(y) print(y) z=[2,5] z=z+[1] print(z) 代码的输出为: [2, 5] [2, 5, 1] 我理解y未修改为[2,5,1]。但是,y被重新分配到一个新列表,它是[2,5,1],对吗?那么为什么y仍然引用原始值呢如果z的值已更改,为什么不更改y? 另外,我刚才问了一个和这个差不多的问题。那个问题被标记为另一个问题的重复。然而,我认为他们有点不同。这就是我再次发布我

我有以下代码:

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


z=[2,5]
z=z+[1]
print(z)
代码的输出为:

[2, 5]
[2, 5, 1]
我理解y未修改为
[2,5,1]
。但是,y被重新分配到一个新列表,它是
[2,5,1]
,对吗?那么为什么y仍然引用原始值呢如果z的值已更改,为什么不更改y?


另外,我刚才问了一个和这个差不多的问题。那个问题被标记为另一个问题的重复。然而,我认为他们有点不同。这就是我再次发布我的问题的原因。我想我一定错过了函数的某些方面。

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

两个选项:

  • 或者让函数返回新列表:

    def proc2(p):
        return p + [1]
    
  • 或者,让它在适当的位置修改
    p
    (并可以选择返回以进行更清晰的编码):

    def proc2(p):
    p+=[1]#这与p=p+[1]并不完全相同
    返回p#
    y被重新分配到新列表

    不,代码中只有一个
    y=…
    赋值

    执行函数时会发生以下情况:

    # 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.
    
    因此,您的函数计算一个结果(一个新列表),在函数范围内指定名称
    p
    ,然后
    p
    在函数退出后立即丢失

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

    >>> def proc2(p):
    ...     p = p + [1]
    ...     return p
    ... 
    >>> y = [2,5]
    >>> y = proc2(y)
    >>> y
    [2, 5, 1]
    
    请注意,即使您的函数中有一个
    y=…
    赋值,该名称也是函数的局部名称,外部作用域也不关心:

    >>> def proc2(y):
    ...     y = y + [1]
    ... 
    >>> y = [2,5]
    >>> proc2(y)
    >>> y
    [2, 5]
    
    最后,您可以告诉Python,您指的是函数体中的全局
    y
    ,但这被认为是糟糕的风格(在这里和大多数其他情况下都是如此)


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

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

    proc2()
    中,添加
    p
    列表,然后将
    p
    重新分配给较长的列表。正如您所提到的,这不会影响仍然指向较短列表的
    y
    。但是,在第二个示例中,
    z
    实际上被重新分配以指向附加列表。分配给
    z
    的原始列表的值实际上没有更改。你只是不再引用它了。如果您在
    z+=1
    之前打印了例如
    old_z=z
    ,然后在之后打印
    old_z
    ,您会看到这一点。行为没有差异。
    p=p+[1]
    不会修改先前引用的列表。它修改变量
    p
    ,以引用新列表。另一个仍然引用旧列表的变量将不会受到影响。@jornsharpe您所说的,我完全理解。但是,在运行
    proc2(y)
    之后,y现在应该指向新列表
    [2,5,1]
    。那么,为什么当我打印y时,python说y仍然指向
    [2,5]
    ?因为它仍然引用旧列表?只有局部变量p被重新赋值。我同意你所说的,除了“如果你不想写一个改变输入列表的函数”。正如@jornsharpe所提到的,分配给
    p
    的原始列表的值,即输入列表[2,5],实际上没有发生突变。只是
    p
    被重新分配到另一个列表[2,5,1]。你同意吗?@failbetter我从来没有说过你原来的函数会改变你的输入列表。我想说的是,你必须返回一个值,这样你的函数才能做一些有用的事情,除非你改变输入参数。明白了。谢谢
    >>> def proc2(y):
    ...     y = y + [1]
    ... 
    >>> y = [2,5]
    >>> proc2(y)
    >>> y
    [2, 5]
    
    >>> def proc2():
    ...     global y
    ...     y = y + [1]
    ... 
    >>> y = [2,5]
    >>> proc2()
    >>> y
    [2, 5, 1]