为了账号安全,请及时绑定邮箱和手机立即绑定

列表更改意外地反映在子列表中

列表更改意外地反映在子列表中

偶然的你 2019-05-20 16:24:02
我需要在Python中创建一个列表列表,所以我输入以下内容:myList = [[1] * 4] * 3列表看起来像这样:[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]然后我改变了最里面的一个值:myList[0][0] = 5现在我的列表看起来像这样:[[5, 1, 1, 1], [5, 1, 1, 1], [5, 1, 1, 1]]这不是我想要或期望的。有人可以解释一下发生了什么,以及如何解决这个问题?
查看完整描述

6 回答

?
繁花不似锦

TA贡献1851条经验 获得超4个赞

实际上,这正是您所期望的。让我们分解这里发生的事情:

你写

lst = [[1] * 4] * 3

这相当于:

lst1 = [1]*4lst = [lst1]*3

这意味着lst是一个包含3个元素的列表lst1。这意味着以下两行是等效的:

lst[0][0] = 5lst1[0] = 5

就像lst[0]什么一样lst1

要获得所需的行为,您可以使用列表理解:

lst = [ [1]*4 for n in xrange(3) ]

在这种情况下,对每个n重新计算表达式,从而得到不同的列表。


查看完整回答
反对 回复 2019-05-20
?
繁华开满天机

TA贡献1816条经验 获得超4个赞

[[1] * 4] * 3

甚至:


[[1, 1, 1, 1]] * 3

创建一个引用内部[1,1,1,1]3次的列表- 而不是内部列表的三个副本,因此每次修改列表(在任何位置)时,您都会看到三次更改。


它与此示例相同:


>>> inner = [1,1,1,1]

>>> outer = [inner]*3

>>> outer

[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]

>>> inner[0] = 5

>>> outer

[[5, 1, 1, 1], [5, 1, 1, 1], [5, 1, 1, 1]]

它可能不那么令人惊讶。


查看完整回答
反对 回复 2019-05-20
?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

除了正确解释问题的接受答案之外,在列表理解中,如果使用python-2.x xrange(),则返回一个更有效的生成器(range()在python 3中执行相同的工作)_而不是一次性变量n

[[1]*4 for _ in xrange(3)]      # and in python3 [[1]*4 for _ in range(3)]

此外,作为更多Pythonic方式,您可以使用它itertools.repeat()来创建重复元素的迭代器对象:

>>> a=list(repeat(1,4))[1, 1, 1, 1]>>> a[0]=5>>> a[5, 1, 1, 1]

PS使用numpy的,如果你只是想创建1或0,你可以使用数组np.onesnp.zeros和/或其他使用次数np.repeat()

In [1]: import numpy as npIn [2]: In [2]: np.ones(4)Out[2]: array([ 1.,  1.,  1.,  1.])In [3]: np.ones((4, 2))Out[3]: array([[ 1.,  1.],
       [ 1.,  1.],
       [ 1.,  1.],
       [ 1.,  1.]])In [4]: np.zeros((4, 2))Out[4]: array([[ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.]])In [5]: np.repeat([7], 10)Out[5]: array([7, 7, 7, 7, 7, 7, 7, 7, 7, 7])


查看完整回答
反对 回复 2019-05-20
?
慕神8447489

TA贡献1780条经验 获得超1个赞

简单来说,这种情况正在发生,因为在python中一切都通过引用工作,所以当你创建一个列表列表时,你基本上会遇到这样的问题。

要解决您的问题,您可以执行以下任一操作:1。对numpy.empty使用numpy数组文档 2.在到达列表时附加列表。如果你愿意,你也可以使用字典


查看完整回答
反对 回复 2019-05-20
?
精慕HU

TA贡献1845条经验 获得超8个赞

Python容器包含对其他对象的引用。看这个例子:

>>> a = []>>> b = [a]>>> b[[]]>>> a.append(1)>>> b[[1]]

在这b是一个列表,其中包含一个作为列表引用的项目a。这个清单a是可变的。

将列表乘以整数等效于将列表多次添加到自身(请参阅常用序列操作)。继续这个例子:

>>> c = b + b>>> c[[1], [1]]>>>>>> a[0] = 2>>> c[[2], [2]]

我们可以看到列表c现在包含两个与list a相同的引用c = b * 2

Python FAQ还包含对此行为的说明:如何创建多维列表?


查看完整回答
反对 回复 2019-05-20
  • 6 回答
  • 0 关注
  • 652 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信