2016-08-18 56 views
0

我正在尋找一個包含類對象列表的類對象的深層副本,每個類都有自己的一套東西。這些對象不包含任何比整數和列表更令人興奮的東西(沒有字母,沒有發生器等待屈服等)。我正在循環執行500-800個對象之間的深層複製,並且它確實減慢了程序的速度。我意識到這已經是低效了;它目前無法更改。它的外觀複製嵌套的自定義對象:深層複製的替代方案

例子:

import random 
import copy 

class Base: 
    def __init__(self, minimum, maximum, length): 
     self.minimum = minimum 
     self.maximum = maximum 
     self.numbers = [random.randint(minimum, maximum) for _ in range(length)] 
     # etc 

class Next: 
    def __init__(self, minimum, maximum, length, quantity): 
     self.minimum = minimum 
     self.maximum = maximum 
     self.bases = [Base(minimum, maximum, length) for _ in range(quantity)] 
     # etc 

因爲行動我執行的對象,我不能淺拷貝。我需要的內容被新的變量所擁有:

> first = Next(0, 10, 5, 10) 
> second = first 
> first.bases[0].numbers[1] = 4 
> print(first.bases[0].numbers) 
> [2, 4, 3, 3, 8] 
> print(second.bases[0].numbers) 
> [2, 4, 3, 3, 8] 
> 
> first = Next(0, 10, 5, 10) 
> second = copy.deepcopy(first) 
> first.bases[0].numbers[1] = 4 
> print(first.bases[0].numbers) 
> [8, 4, 7, 9, 9] 
> print(second.bases[0].numbers) 
> [8, 11, 7, 9, 9] 

我已經嘗試了幾種不同的方法,如使用JSON序列化和重新加載數據,但在我的測試中,它不是已經將近速度不夠快,因爲我堅持每次重新分配所有變量。由於嵌套對象,我試圖拔掉一個巧妙的self.__dict__ = dct沒有奏效。

任何想法如何有效地深度複製乘法嵌套的Python對象而不使用copy.deepcopy?

+1

您可能想要考慮如何將數據項存儲爲基元(例如整數和字符串)而不是Python對象。複製這些會更有效率。也許數組模塊甚至是cython語言都會有用。 –

回答

1

基於cherish的回答here,pickle.loads(pickle.dumps(first))的工作速度是每次呼叫的兩倍。由於測試時出現了無關的錯誤,我最初寫了它,但在重新測試時,它在我的需求中表現良好。

3

copy.deepcopy尋找的第一件事情之一是,如果對象定義it's own __deepcopy__ method因此,不是每次只需定義自己的過程就知道如何複製對象。

它需要你定義一個Base對象,而隨機岬的副本使用的任何元素的一種方式,但如果你能找到複製的對象更有效的方法,你應該把它定義爲一個__deepcopy__方法加快複製過程。

+0

我不確定自定義'__deepcopy__'在這裏可以提供多大的幫助。默認的實現已經複製了所有的屬性,並且避免了在新對象上調用'__init__',所以你不會遇到隨機事件的任何問題。我認爲改善性能的唯一明確方法是大幅改變數據結構(例如,使用'numpy'數組或其他東西,而不是對象列表),或者改變整個算法以避免所有複製的需要。 – Blckknght

+0

我嘗試了這一點,並沒有得到我期望的速度增益(毫無疑問,我的錯誤是如何實現它的)。我發現使用'pickle.loads(pickle.dumps(first))'爲我的目的工作的速度是deepcopy的兩倍。謝謝您的幫助! –