python - 运算符分配的列表列表不能引用特定的列表元素
问题描述
我正在设置一个以相同行开头的二维矩阵。当我使用 lines=n*[list(string)] 创建列表列表以创建 n 个相同字符列表的列表时,它似乎有效。但是,当我尝试将特定值分配给一行中的元素时,它会被复制到所有行中。
我在 Jupyter Notebook 中做了以下操作。显示代码和输出。我还打印了矩阵中特定元素的 id(),同时试图弄清楚发生了什么。如果我用乘法设置矩阵,所有行似乎都在同一个地址。并且对元素进行分配会更改所有行。当我对列表进行硬编码时,元素以相同的地址开始,但是当我进行分配时,地址会发生变化。
Python真的应该像这样工作吗?
这是不起作用的...
lines=11*[list(' | | ')] # Initialize matrix a list of lists
lines[0][0]='0'
for i in lines: print(i)
print('address of 0,0: '+str(id(lines[0][0])))
print('address of 1,0: '+str(id(lines[1][0])))
print('address of 2,0: '+str(id(lines[2][0])))
输出...
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
address of 0,0: 2043952387048
address of 1,0: 2043952387048
address of 2,0: 2043952387048
这是有效的...
lines=[[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '], # Initialize matrix with data.
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']]
lines[0][0]='0'
for i in lines: print(i)
print('address of 0,0: '+str(id(lines[0][0])))
print('address of 1,0: '+str(id(lines[1][0])))
print('address of 2,0: '+str(id(lines[2][0])))
输出...
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
address of 0,0: 2043952387048
address of 1,0: 2043951596632
address of 2,0: 2043951596632
解决方案
当你这样做
lines=11*[list(' | | ')]
你只打电话list(' | | ')
一次。它列出了一个列表,并且同一个列表被引用了 11 次。它相当于:
temp = list(' | | ')
lines = 11*[temp]
只有一个temp
列表,这将创建一个包含 11 个对该列表的引用的列表。乘以一个列表只会复制容器的外部结构,它不会复制它所引用的对象。
利用:
lines = [list(' | | ') for _ in range(11)]
所以它会调用list()
11 次,每次都会创建一个新列表。
推荐阅读
- python - 从 2 个 DataFrame 合并到 1 个
- flutter - 在 Flutter 中仅更改状态栏的颜色
- c# - 如何使用 C# 获取方法的内存使用情况?
- algorithm - 我想我写的代码是对的,但我的 Rabin Karp 似乎不起作用
- django - 令人耳目一新的音频使他们无法收听
- python - 在 pyppeteer 中获取新标签页的 URL
- java - 如何制作倒置的二维三角形数组并用它的索引之和填充它的值?
- php - 如何在不允许下载的情况下提供 php 页面?
- c# - 如何迭代字典json对象
- javascript - 将 Lua 有限状态机类从 CS50 游戏转换为 javascript