python中的list和list[:]有啥区别?

Posted

技术标签:

【中文标题】python中的list和list[:]有啥区别?【英文标题】:What is the difference between list and list[:] in python?python中的list和list[:]有什么区别? 【发布时间】:2011-05-04 03:39:29 【问题描述】:

listlist[:] 在 python 中的区别是什么?

【问题讨论】:

【参考方案1】:

读取时list是对原始列表的引用,list[:]浅拷贝列表。

分配时,list(重新)绑定名称,list[:] 切片分配,替换之前列表中的内容。

另外,不要使用 list 作为名称,因为它会影响内置。

【讨论】:

分配时哪个更快?列表或列表[:]【参考方案2】:

后者是对列表副本的引用,而不是对列表的引用。所以它非常有用。

>>> li = [1,2,3]
>>> li2 = li
>>> li3 = li[:]
>>> li2[0] = 0
>>> li
[0, 2, 3]
>>> li3
[1, 2, 3]

【讨论】:

【参考方案3】:

li[:] 创建原始列表的副本。但它并不引用同一个列表对象。因此,您不必冒险更改由 li[:] 创建的副本来更改原始列表。

例如:

>>> list1 = [1,2,3]
>>> list2 = list1
>>> list3 = list1[:]
>>> list1[0] = 4
>>> list2
[4, 2, 3]
>>> list3
[1, 2, 3]

这里list2 是通过更改list1 而更改的,但list3 不会更改。

【讨论】:

【参考方案4】:

将第一个list 应用于变量将创建对原始列表的引用。 第二个list[i] 将创建一个浅拷贝。

例如:

foo = [1,2,3]
bar = foo
foo[0] = 4

bar 和 foo 现在将是:

[4,2,3]

但是:

foo = [1,2,3]
bar = foo[:]
foo[0] = 4

结果将是:

bar == [1,2,3]
foo == [4,2,3]

: 是切片。

【讨论】:

【参考方案5】:

但是,如果列表元素本身就是列表,那么即使list1 = list[:] 也存在问题。考虑:

>>> a = [[1,2,3],[4,5,6],[7,8,9]]
>>> b = a[:]
>>> b[0].remove(2)
>>> b 
[[1, 3], [4, 5, 6], [7, 8, 9]]
>>> a
[[1, 3], [4, 5, 6], [7, 8, 9]]

发生这种情况是因为复制到 b 的每个列表元素本身就是一个列表,并且这种列表复制涉及与普通 list1 = list2 相同的问题。 我发现的最短方法是以这种方式显式复制每个列表元素:

>>> a = [[1,2,3],[4,5,6],[7,8,9]]
>>> b=[[j for j in i] for i in a]   
>>> b
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> b[0].remove(2)
>>> b
[[1, 3], [4, 5, 6], [7, 8, 9]]
>>> a
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

当然,对于嵌套列表中每增加一层嵌套,复制代码就会加深一个额外的内联 for 循环。

【讨论】:

如果您在外部列表中有不同或未知的嵌套级别,这将遇到严重问题(i 可能不可迭代)如果您有嵌套列表,则应该使用 copy模块,使用 b = copy.deepcopy(a) 而不是嵌套的 for 循环。【参考方案6】:

第一个引用原始列表。第二个指向原始列表的副本。 看看这个!

>>> a = [1, 2, 3]
>>> b = a
>>> c = a[:]
>>> a == b
True
>>> a is b
True
>>> a == c
True
>>> a is c
False
>>> a.__repr__
<method-wrapper '__repr__' of list object at 0x7f87a9ba3688>
>>> a.__repr__()
'[1, 2, 3]'
>>> b.__repr__
<method-wrapper '__repr__' of list object at 0x7f87a9ba3688>
>>> c.__repr__
<method-wrapper '__repr__' of list object at 0x7f87ad352988>

请注意,ab 都指向地址 0x7f87a9ba3688,而 c 指向 0x7f87ad352988. 区别非常明显。ab 都引用原始列表对象。 而 c 指向(原始列表的)副本,因此它位于不同的位置。

【讨论】:

【参考方案7】:

另一个有用的例子是给列表和列表[:]分配不同的类型。例如,

l = [1,2,3]
a = numpy.array([4,5,6])
l = a
print(l)

结果是一个numpy数组:

array([4, 5, 6])

同时,

l = [1,2,3]
a = numpy.array([4,5,6])
l[:] = a
print(l)

结果是一个列表:

[4, 5, 6]

【讨论】:

以上是关于python中的list和list[:]有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中,f.readlines() 和 list(f) 有啥区别

LIST.append(1) 和 LIST = LIST + [1] (Python) 有啥区别

在 Python 中,“.append()”和“+= []”有啥区别?

List和List之间有啥区别

R中的list()和c()有啥区别,以及如何在函数中传递列表元素

list和vector有啥区别