我想复制嵌套列表 a
,但不知道如何在不使用 copy.deepcopy
函数的情况下实现。
a = [[1, 2], [3, 4]]
我使用了:
b = a[:]
并且
b = a[:][:]
但它们最终都变成了浅拷贝。有什么提示吗?
我想复制嵌套列表 a
,但不知道如何在不使用 copy.deepcopy
函数的情况下实现。
a = [[1, 2], [3, 4]]
我使用了:
b = a[:]
并且
b = a[:][:]
我编写了一个模拟copy.deepcopy
的实现:
def deepcopy(obj):
if isinstance(obj, dict):
return {deepcopy(key): deepcopy(value) for key, value in obj.items()}
if hasattr(obj, '__iter__'):
return type(obj)(deepcopy(item) for item in obj)
return obj
__iter__
方法)。此外,这个解决方案性能较差,并假设类始终可以在构造函数中处理其对象。 - JBernardotype(obj).__init__
不能复制 obj
的情况。但是,考虑到只有6行代码可以证明这个观点,我可以接受这一点。 :-) - Kirk Strausertype(obj)(obj)
的适用范围仅限于内置类型,对于几乎所有的类实例都无效。而且它也不会复制任何不可变类型(似乎 str(s)
直接返回 s
是合理的,因为字符串是不可变的)。但由于唯一既可变又是内置类型的类型是可迭代类型,所以最好只需 return obj
,因为 return type(obj)(obj)
声称复制 obj
,但实际上它几乎从不这样做。 - Benb = [x[:] for x in a]
deepcopy()
。 - Ignacio Vazquez-Abrams这是一个完全的欺骗 - 但适用于“基本类型”列表 - 列表,字典,字符串,数字:
def cheat_copy(nested_content):
return eval(repr(nested_content))
这涉及到强大的安全问题,速度也不会特别快。使用json.dumps和loads将更加安全。
我找到了一种使用递归的方法来实现它。
def deep_copy(nested_content):
if not isinstance(nested_content,list):
return nested_content
else:
holder = []
for sub_content in nested_content:
holder.append(deep_copy(sub_content))
return holder
nested_content.__iter__
,你可以使用 type(nested_content)
来创建一个相同类型的新对象。此外,你实际上并没有复制你的列表内容 - 你正在构建引用原始项目的新列表。 - Kirk Strauser对于递归版本,您需要跟踪一个辅助列表并每次返回。
b=a[:]
确实创建了一个新的列表,但它的元素是对a中原始项的引用。例如:a=[[]];b=a[:];b[0].append(1);print a
生成[[1]]
,因为b中的第一个元素与a中的第一个元素是相同的对象。深度复制将导致两个不同的对象 - 你可以自己试试。 - Kirk Strausera[:]
返回一个包含相同元素的新列表。因为它是一个求值为列表的表达式,所以支持所有列表操作,包括切片。因此,a[:][:]
返回一个包含相同元素的新列表,然后对该列表进行一次新的复制,使其具有相同的元素(仍然与第一个列表相同)。然后a[:][:][:]
只是再次进行复制。无论您多少次使用相同元素创建新列表的副本... 它仍然具有相同的元素。 - Bencopy.deepcopy
在许多情况下也不能立即正确地完成它(您可以提供自己的 copy 和 deepcopy 方法来解决这个问题)。如果您要自己实现此操作,则只能通过进行严格限制的假设来获得简单的结果,例如“我只复制包含内置类型的列表”。 - Ben