【发布时间】:2010-09-16 03:01:27
【问题描述】:
复制列表的最佳方法是什么?我知道以下几种方法,哪一种更好?还是有别的办法?
lst = ['one', 2, 3]
lst1 = list(lst)
lst2 = lst[:]
import copy
lst3 = copy.copy(lst)
【问题讨论】:
标签: python
复制列表的最佳方法是什么?我知道以下几种方法,哪一种更好?还是有别的办法?
lst = ['one', 2, 3]
lst1 = list(lst)
lst2 = lst[:]
import copy
lst3 = copy.copy(lst)
【问题讨论】:
标签: python
如果您想要浅拷贝(不拷贝元素),请使用:
lst2=lst1[:]
如果要进行深拷贝,请使用复制模块:
import copy
lst2=copy.deepcopy(lst1)
【讨论】:
lst2 = list (lst1)
我经常使用:
lst2 = lst1 * 1
如果 lst1 它包含其他容器(如其他列表),您应该使用复制库中的 deepcopy,如 Mark 所示。
更新:解释 deepcopy
>>> a = range(5)
>>> b = a*1
>>> a,b
([0, 1, 2, 3, 4], [0, 1, 2, 3, 4])
>>> a[2] = 55
>>> a,b
([0, 1, 55, 3, 4], [0, 1, 2, 3, 4])
您可能会看到只有一个改变... 我现在将尝试使用列表列表
>>>
>>> a = [range(i,i+3) for i in range(3)]
>>> a
[[0, 1, 2], [1, 2, 3], [2, 3, 4]]
>>> b = a*1
>>> a,b
([[0, 1, 2], [1, 2, 3], [2, 3, 4]], [[0, 1, 2], [1, 2, 3], [2, 3, 4]])
不太可读,让我用 for 打印它:
>>> for i in (a,b): print i
[[0, 1, 2], [1, 2, 3], [2, 3, 4]]
[[0, 1, 2], [1, 2, 3], [2, 3, 4]]
>>> a[1].append('appended')
>>> for i in (a,b): print i
[[0, 1, 2], [1, 2, 3, 'appended'], [2, 3, 4]]
[[0, 1, 2], [1, 2, 3, 'appended'], [2, 3, 4]]
你看到了吗?它也附加到 b[1],所以 b[1] 和 a[1] 是同一个对象。 现在用 deepcopy 试试吧
>>> from copy import deepcopy
>>> b = deepcopy(a)
>>> a[0].append('again...')
>>> for i in (a,b): print i
[[0, 1, 2, 'again...'], [1, 2, 3, 'appended'], [2, 3, 4]]
[[0, 1, 2], [1, 2, 3, 'appended'], [2, 3, 4]]
【讨论】:
copy() 在最后一种情况下不起作用,只要对象内部有引用,就需要deepcopy()。
lst1*1 的技巧非常好......但是,可悲的是,粗略的分析表明它至少比lst1[:] 慢两倍,这比@ 稍快987654330@.
你也可以这样做:
a = [1, 2, 3]
b = list(a)
【讨论】:
[:] 时,该库足够聪明,可以知道正在制作副本,因此它可能会调用一些本机 C 代码来执行此操作。使用list(iterable),它是否知道/关心迭代已经物化,因此可以有效地复制?
我喜欢做:
lst2 = list(lst1)
与 lst1[:] 相比的优势在于相同的成语适用于 dicts:
dct2 = dict(dct1)
【讨论】:
短名单,[:] 是最好的:
In [1]: l = range(10)
In [2]: %timeit list(l)
1000000 loops, best of 3: 477 ns per loop
In [3]: %timeit l[:]
1000000 loops, best of 3: 236 ns per loop
In [6]: %timeit copy(l)
1000000 loops, best of 3: 1.43 us per loop
对于较大的列表,它们都差不多:
In [7]: l = range(50000)
In [8]: %timeit list(l)
1000 loops, best of 3: 261 us per loop
In [9]: %timeit l[:]
1000 loops, best of 3: 261 us per loop
In [10]: %timeit copy(l)
1000 loops, best of 3: 248 us per loop
对于非常大的列表(我尝试了 50MM),它们仍然大致相同。
【讨论】:
您也可以这样做:
import copy
list2 = copy.copy(list1)
这应该和 Mark Roddy 的浅拷贝一样。
【讨论】:
就性能而言,调用list() 与切片相比有一些开销。所以对于短名单,lst2 = lst1[:] 的速度大约是lst2 = list(lst1) 的两倍。
在大多数情况下,list() 更具可读性这一事实可能超过了这一点,但在紧密循环中,这可能是一个有价值的优化。
【讨论】: