python中list和list[:]之间的区别是什么?
python中的python中list和list[:]之间的区别是什么?,python,Python,python中的list和list[:]之间有什么区别?后者是对列表副本的引用,而不是对列表的引用。所以它非常有用 >>> li = [1,2,3] >>> li2 = li >>> li3 = li[:] >>> li2[0] = 0 >>> li [0, 2, 3] >>> li3 [1, 2, 3] 阅读时,list是对原始列表的引用,list[:]shall复制列表 分配时,li
list
和list[:]
之间有什么区别?后者是对列表副本的引用,而不是对列表的引用。所以它非常有用
>>> li = [1,2,3]
>>> li2 = li
>>> li3 = li[:]
>>> li2[0] = 0
>>> li
[0, 2, 3]
>>> li3
[1, 2, 3]
阅读时,
list
是对原始列表的引用,list[:]
shall复制列表
分配时,list
(重新)绑定名称和list[:]
切片分配,替换列表中以前的内容
另外,不要将
列表
用作名称,因为它会遮挡内置项。将第一个列表
应用于变量将创建对原始列表的引用。
第二个列表[i]
将创建一个浅拷贝
例如:
foo = [1,2,3]
bar = foo
foo[0] = 4
>>> list1 = [1,2,3]
>>> list2 = list1
>>> list3 = list1[:]
>>> list1[0] = 4
>>> list2
[4, 2, 3]
>>> list3
[1, 2, 3]
bar和foo现在将:
[4,2,3]
但是:
结果将是:
bar == [1,2,3]
foo == [4,2,3]
:
是切片。但是,如果列表元素本身就是列表,即使是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
循环而加深。li[:]创建原始列表的副本。但它并不引用相同的列表对象。因此,您不会因为更改由li[:]创建的副本而冒险更改原始列表
例如:
foo = [1,2,3]
bar = foo
foo[0] = 4
>>> list1 = [1,2,3]
>>> list2 = list1
>>> list3 = list1[:]
>>> list1[0] = 4
>>> list2
[4, 2, 3]
>>> list3
[1, 2, 3]
此处,通过更改
list1
来更改list2
,但list3
不会更改。第一个列表引用原始列表。第二个指向原始列表的副本。看看这个
>>> 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>
>a=[1,2,3]
>>>b=a
>>>c=a[:]
>>>a==b
真的
>>>a是b
真的
>>>a==c
真的
>>>a是c
假的
>>>报告__
>>>a.报告
'[1, 2, 3]'
>>>b.(报告)__
>>>报告__
请注意,a和b都指向地址0x7f87a9ba3688,而c指向地址0x7f87ad352988差别非常明显。
a和b都引用了原始列表对象。
然而,c指向(原始列表的)副本,因此,它位于不同的位置。另一个有用的示例是为列表和列表[:]指定不同的类型。比如说,
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]
如果外部列表中的嵌套级别不同或未知(
i
可能不可编辑),这将遇到严重问题。如果您有嵌套列表,则应使用模块,使用b=copy.deepcopy(a)
,而不是嵌套for循环。