让我们说
>>> a = [1,2,3,4,5]
我想要一个像
这样的输出>>> b
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]
这是我的代码:
class Child(object):
def get_lines(self):
a = [1,2,3,4,5]
b=[]
c=[]
j=0
for i in a:
print i
b.append(i)
print b
c.insert(j,b)
j=j+1
print c
son= Child()
son.get_lines()
当我在循环中打印列表b
时,它会给出:
1
[1]
2
[1, 2]
3
[1, 2, 3]
4
[1, 2, 3, 4]
5
[1, 2, 3, 4, 5]
,输出为:
[[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]
我在代码中哪里出错?
答案 0 :(得分:5)
b
始终是相同的列表对象(请注意我已将print c
更改为return c
):
>>> map(id, Child().get_lines())
...
[49021616, 49021616, 49021616, 49021616, 49021616]
c
包含对同一列表的五个引用。我想你想要的是:
class Child(object):
def get_lines(self):
a = [1, 2, 3, 4, 5]
return [a[:x+1] for x in range(len(a))]
这为每个步骤的部分(或全部)a
创建浅拷贝:
>>> Child().get_lines()
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]
答案 1 :(得分:2)
替换:
c.insert(j,b)
使用:
c.append(b[:])
再试一次。
您需要制作b
的副本。否则,您会再次添加相同的b
,从而在所有索引处生成完整列表。 'b [:]'复制清单。
此解决方案也是如此,但有点短:
a = [1, 2, 3, 4, 5]
c = []
for i in range(1, len(a) + 1):
c.append(a[:i])
现在c
是:
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]
a[:i]
从头开始对列表a
进行切片,以排除索引i
。
在这种情况下,它会a[:1]
,a[:2]
等等。 a[:1]
制作了一个新列表[1],
a[:2]
新列表[1, 2,]
等等。使用append()
更简单,insert()
。
另一种选择是列表理解:
a = [1, 2, 3, 4, 5]
[a[:i] for i in range(1, len(a) + 1)]
也会导致:
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]
答案 2 :(得分:2)
在这种情况下,您不应该将值附加到列表对象(b)。
由于list
为mutable
,因此在重新分配之前,它将引用内存中完全相同的对象。
>>> b=[]
>>> b.append(1)
>>> id(b)
4337935424
>>> b.append(2)
>>> id(b)
4337935424
>>> b.append(3)
>>> id(b)
4337935424
>>> b = [1, 2, 3, 4]
>>> id(b)
4337942608
以便在您的代码中c
将对同一列表进行五次引用。
它将指示一个新对象,然后(尽可能)将对它的引用插入到原始对象中。
>>> class Child(object):
...
... def get_lines(self):
... a = [1, 2, 3, 4, 5]
... return map(lambda x: a[:x+1], range(len(a)))
...
>>> Child().get_lines()
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]
答案 3 :(得分:1)
您在列表b
中五次插入相同的c
。由于列表实际上包含对象而不是副本的引用,因此您有5次引用相同的b
列表,其中您已连续添加1,2,3,4,5。因此结果。
您必须添加列表b的副本:
def get_lines(self):
a = [1,2,3,4,5]
b=[]
c=[]
j=0
for i in a:
print i
b.append(i)
print b
c.insert(j,b[:]) # forces insertion of a copy
j=j+1
print c
答案 4 :(得分:0)
在循环中,b
的值仍然存在,因为它是一个可变对象。因此,当您打印c
时,会显示b
的最后一个值。
您可以直接使用b
,而不是使用a
作为临时变量,而不是:
class Child(object):
def get_lines(self):
a = [1,2,3,4,5]
b = []
for index, element in enumerate(a, 1):
b.append(x[:index])
return b
son= Child()
son.get_lines()