In Python 2, how to copy list of complex nested elements by value, not reference, regardless of the list's content
我遇到了一些很好的问题和答案,关于按引用和按值(这个,这个和这个)复制列表。不幸的是,所有建议的解决方案都没有从所有嵌套结构中删除引用(尝试b = a[:]、b = list(a)、copy.copy…)。我最后的希望是copy.deepcopy,但当内部某个地方有一个数组时,它不适用于嵌套结构(我正在处理openpyxl列)。我在堆栈底部得到这个错误:
1 2 3
| File"C:\Python27\lib\copy.py", line 257, in _deepcopy_dict
y[deepcopy(key, memo)] = deepcopy(value, memo)
TypeError: unhashable type: 'array.array' |
我的问题是:是否可以创建不带任何引用的列表a的完整副本,而不管a中嵌套了什么?
- 您的错误不是由于deepcopy造成的。相反,您试图将它用作key到dict,这要求key是可哈希类型。
- 在整个结构上调用一次copy.deepcopy,所有内容都是递归复制的:b = copy.deepcopy(a)
- 然而,copy.pypython模块是错误的根源。
- 我想我不明白你们的意思。@克雷克雷默,也许在这个结构里有一些听写,但是为什么它会重要呢?@我就是这么做的。在我的例子中:tmp_columns = deepcopy([r for r in ws.columns]),它抛出TypeError。
- @阿图尔只做了一件事。
- ws.columns是一个生成器,所以我不能直接执行。如果我把它拆分成不同的行,结果是一样的(tmp_columns = [r for r in ws.columns]tmp_columns_no_reference = deepcopy(tmp_columns)也返回TypeError)
确实,你需要的是deepcopy。问题是StyleArray类不实现__deepcopy__。
以下修复程序似乎可以完成此任务:
1 2
| def __deepcopy__(self, memo):
return self.__copy__() |
注:__copy__已经是按值复制的(待核对)。
它还回答了更一般的问题:为了完整复制嵌套结构,非标准嵌套元素必须以某种方式指示如何复制它们自己。
- 谢谢您!回答和解释。明天上班的时候让我检查一下,然后我会把它标为答案。
- 我深入研究了copy模块,文档说This version does not copy types like module, class, function, method, nor stack trace, stack frame, nor file, socket, window, nor array, nor any similar types.是用这个deepcopy定义修改数组模块的正确方法吗?
- 找到答案的一个好方法是测试:克隆,以某种方式更改样式(StyleArray状态),并与原始样式进行比较。我的猜测是,默认情况下,copy模块不会复制数组,因为它可能会悄悄地引入内存和时间损失。不管怎样,这并不意味着这是被禁止的或"错误"的。