开发中,我们时常会使用序列操作:
l = [1,2,3]
l * 2
>>>[17]: [1, 2, 3, 1, 2, 3]
5*'abc'
>>>'abcabcabcabcabc'
python中 + 和 * 都有这个规律,不修改原有的操作对象,而是构建一个全新的序列
我们现在来看两个例子:
一个包含三个列表的列表
board = [['_'] * 3 for i in range(3)]
board
>>>[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
board[1][2] = 'x'
>>>[['_', '_', '_'], ['_', '_', 'x'], ['_', '_', '_']]
这里我们看到我们成功的修改了预期值,我们再看下一个例子
用更简单的建立序列的方法
weird_board = [['_'] * 3] * 3
这样建立是不是比上面的例子要简单的多,但是这个序列有一个问题,就是这个序列里面的的三个对象的指针都是指向同一个地方,
In [33]: for i in [['_'] * 3] * 3:
...: print(id(i))
4446930504
4446930504
4446930504
看到三个对象的内存地址是一致的,那我们再来看看上一个列子里面的对象地址
In [34]: for i in [['_'] * 3 for i in range(3)]:
...: print(id(i))
...:
4447022600
4446945352
4446421896
可以清楚的看到三个地址是不一致的,
这就说明了一个问题:for 循环是连续添加新对象进入列表
现在我们来修改下其中的一个值
In [39]: weird_board[1][2] = 'x'
In [40]: weird_board
Out[40]: [['_', '_', 'x'], ['_', '_', 'x'], ['_', '_', 'x']]
问题出现了,我们只是修改了一个位置的值,但是三个对象全变了,
这个问题的实质还是这就是对象列表里面的一个小坑,希望大家在开发的时候注意这点。
网友评论