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的内存结构
列表中的存储内容,即列表元素对象的的指针。
遍历时的循环变量即每个数据对象本身,而不是存放指向数据对象的指针,所以例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中是针对循环变量所指向的列表中的元素进行修改,这样是可以的。
以上就是问题的原理了,若有错误指出请指出。