我有一个字典,其中值是非嵌套列表(具体来说,键是整数,值是整数列表)。我想对其进行深层复制,这样我就不会修改原始字典中的列表。
我知道我可以使用
copied = copy.deepcopy(original)
Run Code Online (Sandbox Code Playgroud)
然而,由于我知道数据结构的形式,我也可以使用类似的东西
copied = {key:valuelist[:] for (key,valuelist) in original.iteritems()}
Run Code Online (Sandbox Code Playgroud)
这些解决方案之一更好吗?更高效?不太可能导致令人讨厌的意外?
有人告诉我 deepcopy() 带有一些陷阱,但我不太明白是什么。我还想了解使用 deepcopy() 是否比我的代码效率更低(可能是因为它是更通用的解决方案?)还是更高效(可能它在较低级别进行了优化?)。
正如您可能预期的那样,copy.deepcopy比您的第二个解决方案慢得多:
$ python -m timeit "original = {x: range(10) for x in xrange(10)}; copy = {x: v[:] for x,v in original.iteritems()}"
100000 loops, best of 3: 5.41 usec per loop
$ python -m timeit "original = {x: range(1000) for x in xrange(1000)}; copy = {x: v[:] for x,v in original.iteritems()}"
100 loops, best of 3: 17.1 msec per loop
$ python -m timeit "import copy; original = {x: range(10) for x in xrange(10)}; c = copy.deepcopy(original)"
10000 loops, best of 3: 86.4 usec per loop
$ python -m timeit "import copy; original = {x: range(1000) for x in xrange(1000)}; c = copy.deepcopy(original)"
10 loops, best of 3: 1.4 sec per loop
Run Code Online (Sandbox Code Playgroud)
deepcopy比字典理解+列表复制慢得多的原因是:
deepcopy是多用途函数 - 它几乎适用于任何类型的对象deepcopy在Python中实现,而字典理解和列表切片是在较低级别完成的最重要的是
deepcopy递归地复制容器内的元素,而您的字典理解则不会。例子:
>>> import copy
>>> obj = object()
>>> original = {x: [obj] * 10 for x in xrange(10)}
>>> copy1 = {x:v[:] for x,v in original.iteritems()}
>>> copy2 = copy.deepcopy(original)
>>> copy1[0][0] is original[0][0]
True
>>> copy2[0][0] is original[0][0]
False
Run Code Online (Sandbox Code Playgroud)
如您所见,deepcopy复制了obj中包含的内容original,以便copy2列表包含它的副本,而不是其obj本身。与您的字典理解不同,它在创建新的列表对象时保留列表中的元素。
| 归档时间: |
|
| 查看次数: |
1686 次 |
| 最近记录: |