由重复创建的嵌套列表?

时间:2021-10-04 19:45:21

I want to create a nested list by a repetition of a simple list, say

我想通过一个简单列表的重复来创建一个嵌套列表

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

Which results in

这将导致

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

When I change an element of one of the nested lists, the corresponding elements in all other lists also change:

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

y[0][0] = 'z'

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

What should I do in order to get the following list instead of the above change in all list items?

为了在所有列表项中获得以下列表而不是上面的更改,我应该做什么?

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

2 个解决方案

#1


1  

Lists are references in python. Therefore you're making a list of 3 references to the x list with your code the way it is. There are several ways to work around this, and make a real copy of your list, slice is one of them. Slice will return a new list from the primary list based on the slice range.

列表是python中的引用。因此,你用你的代码创建了一个包含3个对x列表的引用的列表。有几种方法可以解决这个问题,制作一个真实的列表,slice就是其中之一。Slice将根据片范围从主列表返回一个新的列表。

Below I simply use loop to loop the number of times you wanted (3) and slice the full range of the x list each time so I return a copy of it. I then just append the resulting slice to the y list.

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

Maybe not the prettiest, but solves this problem.

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

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

print(y)

y[0][0] = 'z'

print(y)

Output:

输出:

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

#2


0  

Let's start from the beginning and explore it a little deep:

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

So Suppose you have two list:

假设你有两个列表

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

And we have to copy both list, now starting from the first list:

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

So first, let's try by general method of copy:

首先,我们用一般的复制方法:

copy=list_1

Now if you are thinking copy copied the list_1 then you can be wrong, let's check it:

如果你想复制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))

output:

输出:

4329485320
4329485320

Surprised ? Ok let's explore it:

惊讶吗?好让我们探索它:

So as we know python doesn't store anything in a variable, Variables are just referencing to the object and object store the value. Here object is list but we created two references to that same object by two different variable names. So both variables are pointing to the same object:

我们知道python不会在变量中存储任何东西,变量只是引用对象,对象存储值。这里的对象是list,但是我们用两个不同的变量名创建了两个对同一个对象的引用。两个变量指向同一个对象

so when you do copy=list_1 what actually it's doing:

复制=list_1时

由重复创建的嵌套列表?

Here in the image list_1 and copy are two variable names but the object is same for both variable which is list

在图像list_1中,复制是两个变量名,但是对象对两个变量都是相同的。

So if you try to modify copied list then it will modify the original list too because the list is only one there, you will modify that list no matter you do from the copied list or from the original list:

所以如果你想修改复制的列表那么它也会修改原始列表因为列表只有一个,无论你从复制的列表还是原始列表中做什么,你都会修改这个列表:

copy[0]="modify"

print(copy)
print(list_1)

output:

输出:

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

So it modified the original list:

所以修改了原列表:

What is the solution then?

那么解决方案是什么呢?

Solution:

解决方案:

Now let's move to a second pythonic method of copying list:

现在我们来看第二种毕达哥拉斯式的复制列表方法:

copy_1=list_1[:]

Now this method fix the thing what we were facing in first issue let's check it:

这个方法修正了我们在第一期中遇到的问题我们来检查一下

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

4338792136
4338791432

So as we can see our both list having different id and it means both variables are pointing to different objects so what actually going on here is:

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

由重复创建的嵌套列表?

Now let's try to modify the list and let's see if we still face the previous problem:

现在我们试着修改一下列表,看看我们是否还面临着前面的问题:

copy_1[0]="modify"

print(list_1)
print(copy_1)

Output:

输出:

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

So as you can see it is not modifying the original list, it only modified the copied list, So we are ok with it.

正如你看到的,它并没有修改原始列表,它只是修改了复制的列表,所以我们没有问题。

So now i think we are done? wait we have to copy the second nested list too so let's try pythonic way:

现在我想我们做完了吗?等等,我们也要复制第二个嵌套的列表,让我们试试毕达哥拉斯的方法:

copy_2=list_2[:]

So list_2 should reference to another object which is copy of list_2 let's check:

所以list_2应该指向另一个对象它是list_2的拷贝让我们检查一下:

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

we get the output:

我们得到的输出:

4330403592 4330403528

Now we can assume both lists are pointing different object so now let's try to modify it and let's see it is giving what we want:

现在我们可以假设两个列表指向不同的对象现在我们试着修改它让我们看看它给出了我们想要的

So when we try:

所以当我们尝试:

copy_2[0][1]="modify"

print(list_2,copy_2)

it gives us output:

它给了我们输出:

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

Now, this is little confusing we used the pythonic way and still, we are facing the same issue.

现在,这有点让人困惑我们用了python的方法,我们仍然面临着同样的问题。

let's understand it:

让我们明白:

So when we do:

所以当我们做的事:

copy_2=list_2[:]

we are actually copying the outer list only, not the nested list, so nested list is same object for both list, let's check:

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

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

output:

输出:

4329485832
4329485832

So actually when we do copy_2=list_2[:] this is what happens:

实际上,copy_2=list_2[:]

由重复创建的嵌套列表?

It creates the copy of list but only outer list copy, not the nested list copy, nested list is same for both variable so if you try to modify the nested list then it will modify the original list too because nested list object is same for both nested list.

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

So what is the solution?

那么解决方案是什么呢?

Solution is deep copy

解决方案是深拷贝

from copy import deepcopy
deep=deepcopy(list_2)

So now let's check it:

现在我们来检查一下

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

output:

输出:

4322146056 4322148040

both id are different, now let's check nested list id:

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

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

output:

输出:

4322145992
4322145800

As you can see both id are different so we can assume that both nested list are pointing different object now.

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

So when you do deep=deepcopy(list_2) what actually happens:

当你做deep=deepcopy(list_2)时实际发生了什么:

由重复创建的嵌套列表?

So both nested list are pointing different object and they have seprate copy of nested list now.

所以这两个嵌套列表都指向不同的对象它们现在已经分离了嵌套列表的副本。

Now let's try to modify the nested list and let's see if it solved the previous issue or not:

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

so if we do:

如果我们做的事:

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

output:

输出:

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

So, as you can see, it didn't modify the original nested list, it only modified the copied list.

如您所见,它没有修改原始的嵌套列表,而是修改了复制的列表。

#1


1  

Lists are references in python. Therefore you're making a list of 3 references to the x list with your code the way it is. There are several ways to work around this, and make a real copy of your list, slice is one of them. Slice will return a new list from the primary list based on the slice range.

列表是python中的引用。因此,你用你的代码创建了一个包含3个对x列表的引用的列表。有几种方法可以解决这个问题,制作一个真实的列表,slice就是其中之一。Slice将根据片范围从主列表返回一个新的列表。

Below I simply use loop to loop the number of times you wanted (3) and slice the full range of the x list each time so I return a copy of it. I then just append the resulting slice to the y list.

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

Maybe not the prettiest, but solves this problem.

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

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

print(y)

y[0][0] = 'z'

print(y)

Output:

输出:

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

#2


0  

Let's start from the beginning and explore it a little deep:

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

So Suppose you have two list:

假设你有两个列表

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

And we have to copy both list, now starting from the first list:

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

So first, let's try by general method of copy:

首先,我们用一般的复制方法:

copy=list_1

Now if you are thinking copy copied the list_1 then you can be wrong, let's check it:

如果你想复制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))

output:

输出:

4329485320
4329485320

Surprised ? Ok let's explore it:

惊讶吗?好让我们探索它:

So as we know python doesn't store anything in a variable, Variables are just referencing to the object and object store the value. Here object is list but we created two references to that same object by two different variable names. So both variables are pointing to the same object:

我们知道python不会在变量中存储任何东西,变量只是引用对象,对象存储值。这里的对象是list,但是我们用两个不同的变量名创建了两个对同一个对象的引用。两个变量指向同一个对象

so when you do copy=list_1 what actually it's doing:

复制=list_1时

由重复创建的嵌套列表?

Here in the image list_1 and copy are two variable names but the object is same for both variable which is list

在图像list_1中,复制是两个变量名,但是对象对两个变量都是相同的。

So if you try to modify copied list then it will modify the original list too because the list is only one there, you will modify that list no matter you do from the copied list or from the original list:

所以如果你想修改复制的列表那么它也会修改原始列表因为列表只有一个,无论你从复制的列表还是原始列表中做什么,你都会修改这个列表:

copy[0]="modify"

print(copy)
print(list_1)

output:

输出:

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

So it modified the original list:

所以修改了原列表:

What is the solution then?

那么解决方案是什么呢?

Solution:

解决方案:

Now let's move to a second pythonic method of copying list:

现在我们来看第二种毕达哥拉斯式的复制列表方法:

copy_1=list_1[:]

Now this method fix the thing what we were facing in first issue let's check it:

这个方法修正了我们在第一期中遇到的问题我们来检查一下

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

4338792136
4338791432

So as we can see our both list having different id and it means both variables are pointing to different objects so what actually going on here is:

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

由重复创建的嵌套列表?

Now let's try to modify the list and let's see if we still face the previous problem:

现在我们试着修改一下列表,看看我们是否还面临着前面的问题:

copy_1[0]="modify"

print(list_1)
print(copy_1)

Output:

输出:

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

So as you can see it is not modifying the original list, it only modified the copied list, So we are ok with it.

正如你看到的,它并没有修改原始列表,它只是修改了复制的列表,所以我们没有问题。

So now i think we are done? wait we have to copy the second nested list too so let's try pythonic way:

现在我想我们做完了吗?等等,我们也要复制第二个嵌套的列表,让我们试试毕达哥拉斯的方法:

copy_2=list_2[:]

So list_2 should reference to another object which is copy of list_2 let's check:

所以list_2应该指向另一个对象它是list_2的拷贝让我们检查一下:

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

we get the output:

我们得到的输出:

4330403592 4330403528

Now we can assume both lists are pointing different object so now let's try to modify it and let's see it is giving what we want:

现在我们可以假设两个列表指向不同的对象现在我们试着修改它让我们看看它给出了我们想要的

So when we try:

所以当我们尝试:

copy_2[0][1]="modify"

print(list_2,copy_2)

it gives us output:

它给了我们输出:

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

Now, this is little confusing we used the pythonic way and still, we are facing the same issue.

现在,这有点让人困惑我们用了python的方法,我们仍然面临着同样的问题。

let's understand it:

让我们明白:

So when we do:

所以当我们做的事:

copy_2=list_2[:]

we are actually copying the outer list only, not the nested list, so nested list is same object for both list, let's check:

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

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

output:

输出:

4329485832
4329485832

So actually when we do copy_2=list_2[:] this is what happens:

实际上,copy_2=list_2[:]

由重复创建的嵌套列表?

It creates the copy of list but only outer list copy, not the nested list copy, nested list is same for both variable so if you try to modify the nested list then it will modify the original list too because nested list object is same for both nested list.

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

So what is the solution?

那么解决方案是什么呢?

Solution is deep copy

解决方案是深拷贝

from copy import deepcopy
deep=deepcopy(list_2)

So now let's check it:

现在我们来检查一下

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

output:

输出:

4322146056 4322148040

both id are different, now let's check nested list id:

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

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

output:

输出:

4322145992
4322145800

As you can see both id are different so we can assume that both nested list are pointing different object now.

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

So when you do deep=deepcopy(list_2) what actually happens:

当你做deep=deepcopy(list_2)时实际发生了什么:

由重复创建的嵌套列表?

So both nested list are pointing different object and they have seprate copy of nested list now.

所以这两个嵌套列表都指向不同的对象它们现在已经分离了嵌套列表的副本。

Now let's try to modify the nested list and let's see if it solved the previous issue or not:

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

so if we do:

如果我们做的事:

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

output:

输出:

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

So, as you can see, it didn't modify the original nested list, it only modified the copied list.

如您所见,它没有修改原始的嵌套列表,而是修改了复制的列表。