Python 版本测试为 3.6.7
Python 3.6.7 (default, Oct 22 2018, 11:32:17)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.6.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: board = [[''] * 3 for i in range(3)]
In [2]: print(board)
[['', '', ''], ['', '', ''], ['', '', '']]
In [3]: board[1][2] = "X"
In [4]: print("change",board)
change [['', '', ''], ['', '', 'X'], ['', '', '']] # 可以看到x已经被赋值
In [5]:
下面就是意外版本了
In [7]: weird_board = [['_'] * 3] * 3
In [8]: print(weird_board)
[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
In [9]: weird_board[1][2] = '0'
In [10]: print(weird_board)
[['_', '_', '0'], ['_', '_', '0'], ['_', '_', '0']] # 这里应该是改变一个数据 但是改变了每个都改变了
In [11]:
错误解释
错误的代码中 外面的列表其实包含 3 个指向同一个列表的引用。当我们不做修改
的时候,看起来都还好。 一旦我们试图标记第 1 行第 2 列的元素,就立马暴露了列表内的 3
个引用指向同一个对象的事实。
总结:
如果我们对列表操作的时候 生成一定要使用 for i in range() 或者使用迭代的方式,如果使用 * 的方式会使Python生成的列表指向同一个地址,改变一个就改变了全部.