为什么用list操作会产生不同的结果?

时间:2020-02-01 18:01:06

标签: python list

所以我在做Jacobi算法来近似方程组的解,在处理list时遇到了我不了解的几件事。 可以说我有这三个功能

Mockito.mock(Application::class.java)

Func1打印

def func1 (list):
    list_old = list
    list[0] = 99

    print(list_old)
    print(list)

def func2 (list):
    list_old = list.copy()
    list[0] = 99

    print(list_old)
    print(list)

def func3 (list):
    list_old = list
    list = [9,9,9]

    print(list_old)
    print(list)

list = [0,0,0]
func1(list)
func2(list)
func3(list)

Func2打印

[99, 0, 0] # List_old
[99, 0, 0] # List

Func3打印

[0, 0, 0] # List_old
[99, 0, 0] # List

所以我的问题是: 1)为什么func1的List [0]修改list_old?我认为这与指针和内存空间有关,但我不确定,也没有找到任何能解释这一点的东西。 2)为什么在func3中list_old不能修改?不应该像func1一样吗?

2 个答案:

答案 0 :(得分:1)

@ggorlen所说的差不多。 python变量(如列表)的工作方式是将它们存储在内存中的特定位置。通过将列表变量传递给函数,然后对其进行修改,您正在对其在内存中的特定地址进行修改,因此,即使您离开函数func1,例如,您也修改了原始列表并对其进行了调用。

您使用.copy()在func2中所做的事情是在内存中的另一个位置创建另一个列表。因此,对该列表的修改不会影响对原始列表的修改,反之亦然(此外,由于func1中的修改是在复制之前进行的,因此它们仍会出现在新的复制列表中)。

现在,要回答您的问题,在func1中list_old与func2中的list_old不同,变量名list_old对于func1和func2函数都是本地的,并且指向不同的列表。 func1中的list_old指向函数之外的第一行代码中声明的原始列表。 func2中的list_old指向一个新创建的副本,这两个变量是不同的。在func3中,list_old = list正在将list_old分配给原始列表,但是您有list = [9,9,9],这将创建一个新列表,因此在内存中具有新地址。因此,list_old和func3中的list指向两个内存中的不同位置。

关于python https://medium.com/@tyastropheus/tricky-python-ii-parameter-passing-for-mutable-immutable-objects-10e968cbda35中的变量的好帖子

答案 1 :(得分:0)

@Dmitry指出了不可变性和可变性,列表类型与python中的其他类型是可变的,这意味着对列表的操作会更改列表本身,而其他不可更改的对象(如字符串)在操作时会在内存中创建新实例。下面的代码更好地说明了这一点:

lstA = [0, 0, 0]
lstB = lstA
print(lstA is lstB) # True
# change list B
lstB[0] = 9
print(lstA is lstB) # keeps True
strA = "A string"
strB = strA
print(strA is strB) # True
# Change strB
srtB[0] = "B" # Ops! item assignment not supported (immutable object)
# Then let's do it in another way
strB = "B" + strA[1:] # strB = "B string"
print(strA is strN) # False (other string was created)