Python列表便利时修改值问题记录

使用python的过程中遇到的一个问题:在遍历列表时,若直接对循环中的循环变量进行修改时,有时候无法改变,有时候可以改变。


看一下两个例子:

# Example1
arr = [1, 2, 3, 4, 5]
for i in a:
    if i = 2:
        i = 6
print(arr)

# [1, 2, 3, 4, 5]
# 值并为发生改变
# Example2
arr = [[1, 2, 3], [4, 5, 6]]
for item in arr:
    if item[1] == 2:
        item[1] = 7
print(arr)

# [[1, 7, 3], [4, 5, 6]]
# 值变了

从上述两个例子我们发现,同样是修改一个列表中的某个值,第二个例子中的值被修改成功,而第一个例子未修改成功。


再看一个例子:

# Example3
arr = [(1, 2, 3), (4, 5, 6)]
for item in arr:
    if item[1] == 2:
        item[1] == 7
print(arr)

# [(1, 2, 3), (4, 5, 6)]
# 值未发生改变

可以发现列表中元组的值没有发生改变。至此,有人会会觉得就只是Python对象中的可变对象和不可变对象导致的区别。那么咋们再来看一个例子:

# Example4
arr = [[1, 2, 3], [4, 5, 6]]
for item in arr:
    if item[1] == 2:
        item = [2, 3, 4]
print(arr)

# [[1, 2, 3], [4, 5, 6]]
# 值未发生改变

同样是修改列表中的值,为什么第二个例子可以,而第四个不行?


其实我们要弄懂这个问题,我们需要知道两点。

  • 可变对象和不可变对象

    我们自己定义的变量只是相当于对某个数据对象的一个引用,即变量中并不是直接装入数据对象,而只是数据对象的内存地址,即一个指向数据内存的指针。

    当我们对指向不可变数据对象的变量进行修改时,原内存空间并为发生改变,只不过是修改了变量中的指针,让其指向修改后的数据对象的内存地址。

    而当我们对指向可变数据对象的变量进行修改时,变量中的指针并为修改,而是修改数据对象中的值。

    我们常见的可变数据对象:列表(list),字典(dict),集合(set)
    常见的不可变数据对象:元组(tuple),字符串(str),基本数据类型

  • 列表的存储内容和Python的内存结构

    列表中的存储内容,即列表元素对象的的指针。

Python内存.png

遍历时的循环变量即每个数据对象本身,而不是存放指向数据对象的指针,所以例4中直接将一个新列表赋值给循环变量是不起作用的。而若通过数组加下标的方式则可:

for index, item in enumerate(arr):
    if item[1] == 2:
	    arr[index] = [2, 3, 4]
print(arr)

# [[2, 3, 4], [4, 5, 6]]

故很明了了,例2中是针对循环变量所指向的列表中的元素进行修改,这样是可以的。


以上就是问题的原理了,若有错误指出请指出。

posted @ 2021-05-21 21:40  凡璞  阅读(263)  评论(0编辑  收藏  举报
1 2
3 4
5 6