我需要在Python中创建一个列表列表,所以我输入以下内容:
myList = [[1] * 4] * 3
Run Code Online (Sandbox Code Playgroud)
列表看起来像这样:
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
Run Code Online (Sandbox Code Playgroud)
然后我改变了最里面的一个值:
myList[0][0] = 5
Run Code Online (Sandbox Code Playgroud)
现在我的列表看起来像这样:
[[5, 1, 1, 1], [5, 1, 1, 1], [5, 1, 1, 1]]
Run Code Online (Sandbox Code Playgroud)
这不是我想要或期望的.有人可以解释一下发生了什么,以及如何解决这个问题?
我确信这已在某个地方得到解答,但我不确定如何描述它.
假设我想创建一个包含3个空列表的列表,如下所示:
lst = [[], [], []]
Run Code Online (Sandbox Code Playgroud)
这样做我以为我很聪明:
lst = [[]] * 3
Run Code Online (Sandbox Code Playgroud)
但是我发现,在调试了一些奇怪的行为之后,这导致了对一个子列表的追加更新,比如lst[0].append(3),更新整个列表,[[3], [3], [3]]而不是[[3], [], []].
但是,如果我用列表初始化列表
lst = [[] for i in range(3)]
Run Code Online (Sandbox Code Playgroud)
然后做lst[1].append(5)了预期的[[], [5], []]
我的问题是为什么会发生这种情况?有趣的是,如果我这样做
lst = [[]]*3
lst[0] = [5]
lst[0].append(3)
Run Code Online (Sandbox Code Playgroud)
那么单元格0的"连接"就被打破了[[5,3],[],[]],但是我得到了,但lst[1].append(0)仍然会导致[[5,3],[0],[0].
我最好的猜测是在表单中使用乘法[[]]*x会导致Python存储对单个单元格的引用......?
所以我试图根据宽度和高度在Python中生成嵌套列表.这是我到目前为止:
width = 4
height = 5
row = [None]*width
map = [row]*height
Run Code Online (Sandbox Code Playgroud)
现在,这显然不太正确.打印时看起来很好:
[[None, None, None, None],
[None, None, None, None],
[None, None, None, None],
[None, None, None, None],
[None, None, None, None]]
Run Code Online (Sandbox Code Playgroud)
但是尝试将值分配给这样的位置:
map[2][3] = 'foo'
Run Code Online (Sandbox Code Playgroud)
我明白了:
[[None, None, None, 'foo'],
[None, None, None, 'foo'],
[None, None, None, 'foo'],
[None, None, None, 'foo'],
[None, None, None, 'foo']]
Run Code Online (Sandbox Code Playgroud)
很明显,这是因为每个子列表实际上只是引用相同的对象,行,所以更改一个,更改它们.所以这是我最接近的!
如何动态生成嵌套列表?谢谢!
测试替代for _ in range(n)(执行一些动作n时间,即使动作不依赖于值n)我注意到这种模式的另一种表现更快,for _ in [""] * n.
例如:
timeit('for _ in range(10^1000): pass', number=1000000)
Run Code Online (Sandbox Code Playgroud)
返回16.4秒;
然而,
timeit('for _ in [""]*(10^1000): pass', number=1000000)
Run Code Online (Sandbox Code Playgroud)
需要10.7秒.
为什么[""] * 10^1000比range(10^1000)Python 3 快得多?
所有测试都使用Python 3.3完成
我很安静,因为下面用python来解决这个问题
>>> a = [[]]*3
>>> c=[[],[],[]]
>>> a
[[], [], []]
>>> c
[[], [], []]
>>> a == c
True
>>> a[1].append(2)
>>> a
[[2], [2], [2]]
>>> c[1].append(2)
>>> c
[[], [2], []]
Run Code Online (Sandbox Code Playgroud)
我猜的原因是在变量a中,所有三个列表都会向相同的内存区域发送,直到它们以不同的方式使用.这样对吗?使用*运算符之类的东西进行初始化时,我是否应该始终小心?谢谢!
我已经使用Python多年了,但只是注意到一个非常令人困惑的事情.
a=[[]]*3
a[0].append(3)
Run Code Online (Sandbox Code Playgroud)
和
a=[[] for i in range(3)]
a[0].append(3)
Run Code Online (Sandbox Code Playgroud)
即使类型(列表)相同,也不会产生相同的效果.第一个产量a=[[3], [3], [3]],第二个产量a=[[3],[],[]](如预期的那样).
有人有解释吗?