解开由重复创建的嵌套列表?

时间:2018-03-20 04:15:49

标签: python python-3.x list

我想通过重复一个简单的列表创建一个嵌套列表,比如说

x = ['a','b','c']
y = [x] * 3

结果是

[['a', 'b', 'c'], ['a', 'b', 'c'], ['a', 'b', 'c']]

当我更改其中一个嵌套列表的元素时,所有其他列表中的相应元素也会更改:

y[0][0] = 'z'

[['z', 'b', 'c'], ['z', 'b', 'c'], ['z', 'b', 'c']]

为了获得以下列表而不是所有列表项中的上述更改,我该怎么办?

[['z', 'b', 'c'], ['a', 'b', 'c'], ['a', 'b', 'c']]

2 个答案:

答案 0 :(得分:1)

列表是python中的引用。因此,您需要按照原样编写3个对x列表的引用列表。有几种方法可以解决这个问题,并制作列表的真实副本,切片就是其中之一。 Slice将根据切片范围从主列表返回一个新列表。

下面我简单地使用循环来循环你想要的次数(3)并每次切片x列表的整个范围,所以我返回它的副本。然后我将结果切片附加到y列表。

也许不是最漂亮的,但解决了这个问题。

DELIMITER $$
CREATE DEFINER = CURRENT_USER PROCEDURE getReceiptNumber(IN bankcode VARCHAR(10),IN receipttype VARCHAR(10),OUT seq INT)
BEGIN
    UPDATE receipt_number 
    SET seq_number = (seq_number + 1) 
    WHERE bank_code = bankcode AND receipt_type = receipttype;
    SELECT seq_number FROM receipt_number WHERE bank_code = bankcode AND 
receipt_type = receipttype INTO seq; 
END$$

DELIMITER ;

输出:

x = ['a','b','c']
y = []
for n in range(3):
    y.append(x[:])

print(y)

y[0][0] = 'z'

print(y)

答案 1 :(得分:0)

  

让我们从头开始,深入探讨它:

所以假设你有两个清单:

list_1=['01','98']
list_2=[['01','98']]

我们必须复制这两个列表,现在从第一个列表开始:

首先,让我们尝试一般的复制方法:

copy=list_1

现在,如果您认为复制复制了list_1那么您可能错了,让我们检查一下:

The id() function shows us that both variables point to the same list object, i.e. they share this object.
print(id(copy))
print(id(list_1))

输出:

4329485320
4329485320

很惊讶?好吧,让我们探讨一下:

因为我们知道python不会在变量中存储任何内容,Variables只是引用对象而对象存储该值。这里的对象是list,但是我们通过两个不同的变量名创建了对同一个对象的两个引用。所以这两个变量都指向同一个对象:

所以,当你copy=list_1实际上在做什么时:

enter image description here

这里的图像list_1和copy是两个变量名,但两个变量的对象相同,list

因此,如果您尝试修改复制列表,那么它也会修改原始列表,因为列表只有一个,无论您是从复制列表还是从原始列表中修改该列表,都将修改该列表:

copy[0]="modify"

print(copy)
print(list_1)

输出:

['modify', '98']
['modify', '98']

所以它修改了原始列表:

  

那么解决方案是什么?

     

解决方案:

现在让我们转到复制列表的第二种pythonic方法:

copy_1=list_1[:]

现在这个方法解决了我们在第一期中遇到的问题让我们检查一下:

print(id(copy_1))
print(id(list_1))

4338792136
4338791432

因为我们可以看到我们的两个列表都有不同的id,这意味着两个变量都指向不同的对象,所以这里实际发生的是:

enter image description here

现在让我们尝试修改列表,让我们看看我们是否仍然面临上一个问题:

copy_1[0]="modify"

print(list_1)
print(copy_1)

输出:

['01', '98']
['modify', '98']

因为你可以看到它没有修改原始列表,它只修改了复制的列表,所以我们对它没问题。

所以现在我觉得我们已经完成了?等等我们也要复制第二个嵌套列表所以让我们尝试pythonic方式:

copy_2=list_2[:]

因此list_2应该引用另一个对象,它是list_2的副本,让我们检查:

print(id((list_2)),id(copy_2))

我们得到输出:

4330403592 4330403528

现在我们可以假设两个列表都指向不同的对象,所以现在让我们尝试修改它,让我们看看它给出了我们想要的东西:

所以当我们尝试:

copy_2[0][1]="modify"

print(list_2,copy_2)

它为我们提供了输出:

[['01', 'modify']] [['01', 'modify']]

现在,我们使用了pythonic方式,这有点令人困惑,但我们仍面临同样的问题。

让我们理解它:

所以当我们这样做时:

copy_2=list_2[:]

我们实际上只复制外部列表,而不是嵌套列表,所以嵌套列表是两个列表的同一个对象,让我们检查一下:

print(id(copy_2[0]))
print(id(list_2[0]))

输出:

4329485832
4329485832

所以实际上当我们copy_2=list_2[:]时会发生这种情况:

enter image description here

它创建了列表的副本,但只有外部列表副本,而不是嵌套列表副本,嵌套列表对于这两个变量都是相同的,所以如果你试图修改嵌套列表,那么它也会修改原始列表,因为嵌套列表对象是两个嵌套列表都相同。

那么解决方案是什么?

解决方案是deep copy

from copy import deepcopy
deep=deepcopy(list_2)

现在让我们检查一下:

print(id((list_2)),id(deep))

输出:

4322146056 4322148040

两个id都不同,现在让我们检查嵌套列表ID:

print(id(deep[0]))
print(id(list_2[0]))

输出:

4322145992
4322145800

正如你可以看到两个id都不同所以我们可以假设两个嵌套列表现在指向不同的对象。

所以当你deep=deepcopy(list_2)实际发生的事情时:

enter image description here

因此,两个嵌套列表都指向不同的对象,并且它们现在具有单独的嵌套列表副本。

现在让我们尝试修改嵌套列表,看看它是否解决了以前的问题:

所以,如果我们这样做:

deep[0][1]="modify"
print(list_2,deep)

输出:

[['01', '98']] [['01', 'modify']]

因此,正如您所看到的,它没有修改原始的嵌套列表,它只修改了复制的列表。