Python中列表的不一致的可变性。这种不一致性有什么特殊的原因吗?请解释一下。

11 浏览
0 Comments

Python中列表的不一致的可变性。这种不一致性有什么特殊的原因吗?请解释一下。

我想要复制一个二维列表,这样如果我修改一个列表,另一个列表不会被修改。

对于一维列表,我只需这样做:

a = [1, 2]
b = a[:]

现在,如果我修改ba不会被修改。

但是对于二维列表,这种方法不起作用:

a = [[1, 2],[3, 4]]
b = a[:]

如果我修改ba也会被修改。

我该如何解决这个问题?

0
0 Comments

在Python中,列表的可变性存在不一致性。对于这种不一致性的出现,可能有以下几个原因:

1. 列表是可变对象,因此可以通过改变列表中的元素来改变列表本身。这种可变性使得在对列表进行操作时,可能会出现一些意想不到的结果。

2. 在Python中,对列表进行赋值操作时,只是将变量名指向了列表的引用,而没有创建一个新的列表。这意味着,如果两个变量指向同一个列表,那么对其中一个变量进行修改,会影响到另一个变量。

3. Python中的切片操作(例如`x[:]`)会创建一个新的列表,但是其中的元素仍然是原列表中的引用。这也就意味着,对新列表中的元素进行修改,会影响到原列表中对应位置的元素。

为了解决列表可变性的不一致性问题,可以使用以下方法:

1. 使用深拷贝(deepcopy)来创建一个完全独立的列表副本,而不是仅仅复制引用。可以使用`copy.deepcopy()`函数来实现深拷贝。

2. 使用列表推导式来创建一个新的列表,其中对原列表中的每个元素进行拷贝。例如,可以使用`[x[:] for x in a]`来创建一个新的列表副本。

通过以上方法,可以确保创建一个独立的列表副本,避免对原列表的修改对副本产生影响,从而解决列表可变性的不一致性问题。

0
0 Comments

Python中列表的不一致性可变性是由于对嵌套列表(或多维列表)进行b = a[:]复制时,内部子列表仍然引用列表b的内部子列表引起的。

我们可以使用id()函数来检查引用。以下是一个示例:

>>> a = [[1,2],[3,4]]
>>> id(a)
140191407209856    # a的唯一id
>>> b=a
>>> id(b)
140191407209856
>>> b=a[:]        # 使用切片将列表a复制到b
>>> id(b)         
140191407209920   # 列表b的id已更改且与列表a的id不同
>>> id(a[0])      
140191407188544
>>> id(b[0])
140191407188544
>>> id(a[0])==id(b[0])  # a[0]和b[0]的id相同。
True

因此,切片不会更改列表内部对象的引用。

你可以从上面注意到a[0]b[0]的引用是相同的。

当你将一个二维列表复制到另一个列表时,它会添加一个引用,而不是实际的列表。

相反,你可以使用以下方法来解决这个问题:

- b = copy.deepcopy(a)

- b = [item[:] for item in a]

- b = [item.copy() for item in a]

- b = [list(item) for item in a]

- b = [copy.copy(item) for item in a]

- b = []; b.extend(a)

下面是所有可用复制方法的时间复杂度比较(源自source):

1. 10.59秒(105.9us/itn)- copy.deepcopy(old_list)

2. 10.16秒(101.6us/itn)- 使用深拷贝复制类的纯Python Copy()方法

3. 1.488秒(14.88us/itn)- 使用深拷贝复制字典/列表/元组的纯Python Copy()方法

4. 0.325秒(3.25us/itn)- for item in old_list: new_list.append(item)

5. 0.217秒(2.17us/itn)- [i for i in old_list](列表推导式)

6. 0.186秒(1.86us/itn)- copy.copy(old_list)

7. 0.075秒(0.75us/itn)- list(old_list)

8. 0.053秒(0.53us/itn)- new_list = []; new_list.extend(old_list)

9. 0.039秒(0.39us/itn)- old_list[:](列表切片)

b = []; b.extend(a)在这里不起作用-它是浅拷贝,就像b = [item for item in a]一样。

0
0 Comments

在Python中,列表的可变性存在一些不一致的情况。有人可能会问,为什么会存在这种不一致性?下面我将解释这个问题的原因以及可能的解决方法。

首先,让我们来看一下列表的可变性。在Python中,列表是可变的,这意味着我们可以改变列表中的元素,而不改变列表本身的身份。例如,我们可以通过索引来修改列表中的元素,也可以使用append()、extend()等方法来添加新的元素。

然而,当我们将一个列表赋值给另一个变量时,情况就变得复杂了。在某些情况下,赋值操作只是创建了一个指向同一个列表的新的引用,而不是创建一个新的列表。这就导致了一些不一致性的问题。

为了解决这个问题,Python提供了copy模块中的deepcopy()函数。这个函数可以创建一个列表的深拷贝,即创建一个完全独立的列表,而不是一个指向同一个列表的引用。使用deepcopy()函数可以避免列表可变性的不一致性问题。

下面是一个使用deepcopy()函数的示例:

import copy
a = [1, 2, 3]
b = copy.deepcopy(a)

在这个示例中,变量b将是一个完全独立的列表,它的元素与变量a相同,但是它们不共享同一个身份。

需要注意的是,deepcopy()函数不仅会拷贝列表本身,还会拷贝列表中的元素。这意味着,如果列表中的元素也是可变的对象,那么它们也会被深拷贝。

除了使用deepcopy()函数,还有一种常见的解决方法是使用from copy import deepcopy语句。这样可以直接使用deepcopy()函数,而不需要使用模块名作为前缀。

然而,关于使用import语句的方式,不同的人有不同的偏好。有些人喜欢将整个模块导入,以避免命名冲突,而有些人则更喜欢使用模块名作为前缀来调用函数。

列表可变性的不一致性问题可以通过使用deepcopy()函数来解决。深拷贝可以创建一个完全独立的列表,避免了指向同一个列表的引用。另外,根据个人偏好,可以选择使用import语句导入copy模块,或者直接使用from copy import deepcopy语句来使用deepcopy()函数。

0