带列表的Python实例行为

时间:2018-07-13 13:01:32

标签: python python-3.x list

考虑以下Python中的实例行为。

def change(elements):
    elements[0] = 888
    elements = [-3, -1, -2, -3, -4]
    print(elements[0])

numbers = [1, 4, 5]

print(numbers[0])
change(numbers)
print(numbers[0])
print(numbers)

下面的Python代码段会打印

1
-3, 
888 
[888,4,5]

应该打印

1, 
-3, 
-3, 
[-3,-1,-2,-3,-4]

为什么列表中的元素会被成功覆盖,而不是整个列表对象?

5 个答案:

答案 0 :(得分:2)

该列表作为对该函数的引用传递。因此,该列表在全局空间和功能之间共享。第一个更改将修改列表,并且该更改将反映在两个空格中。但是然后您将其分配给list变量。这将在函数中创建一个新列表。原始列表存在于全局空间中,但不再存在于函数中。因此,此后对函数列表所做的所有更改仅在函数内可见。

考虑该实例的另一种方法是,列表是一种容器。函数的第一行更改容器中的内容。第二行(分配)实际上更改了您正在使用的容器。这对于列表来说都是正确的,但对于任何对象都是如此。这就是@Chris_Rands在评论中给出的解决方案起作用的原因:它修改了容器中的内容,而不更改容器。

答案 1 :(得分:1)

这是经典的Python变量命名参考混淆。我真正想做的就是理解这是打印参考以查看发生了什么。

def change(elements):
    elements[0] = 888
    print("ID of elements is: %d",id(elements))
    elements = [-3, -1, -2, -3, -4]
    print("ID of elements is: %d",id(elements))
    print(elements[0])

numbers = [1, 4, 5]
print("ID of number is: %d",id(numbers))

print(numbers[0])
change(numbers)
print(numbers[0])
print(numbers)

>>>> ('ID of number is: %d', 140036366181584)
1
('ID of elements is: %d', 140036366181584)
('ID of elements is: %d', 140036366181944)
-3
888
[888, 4, 5]

此处的ID表示内存中的位置。如果您运行代码,则数字可能会有所不同,但是行为保持不变。

基本上,当您致电

 elements[0] = 888

您实际上是在突变numbers(在我的示例中为140036366181584的同一ID)。

但是,当您致电

elements = [-3, -1, -2, -3, -4]

您正在创建一个新列表(在我的示例中为140036366181944的不同ID),并为其重新分配了本地名称elements 。您只是将名称elements分配给另一个对象。列表不再相同。

因此,在这一点上,您对numbers所做的全部工作就是将其第一个索引更改为值888,这就是输出根据经验显示的内容。

答案 2 :(得分:0)

首先在change函数中,使用外部作用域的elements,该变量作为参数传递并被引用-可以在函数中进行更改,更改后的内容将影响对象,甚至超出本地范围

然后创建elements的本地实例,对其进行修改并结束该函数。由于全局范围内的elements之前已更改,因此您会看到“意外”结果。

检查https://docs.python.org/3/reference/executionmodel.html了解更多详细信息。

答案 3 :(得分:0)

不应该,因为在第一行中,您覆盖了参数elements的第一个值,在第二行中,您为函数定义了新的局部变量

答案 4 :(得分:0)

查看ID将使您了解...

def change(elements):
    print('inner first elements ID ',id(elements))
    elements[0] = 888
    print('inner second elements ID ',id(elements))
    elements = [-3, -1, -2, -3, -4]
    print('inner third elements ID ',id(elements))
    print('inner third numbers ID ',id(numbers))

numbers = [1, 4, 5]
print(numbers[0])
print('outer numbers ID ',id(numbers))
change(numbers)
print('c ',numbers[0])
print('d', numbers)