2011-06-18 27 views
1

我試圖避免在自定義類使用deepcopy的第(一類圖表)生成方法,deepcopy的複製

的圖表有幾個屬性,如頂點,邊等幾個發電機的方法(方法與yield)。

我需要複製圖表:例如H = deepcopy(G)但不使用deepcopy以加速程序。

然後:

  • 如果我不使用新的圖形H deepcopy那麼 生成方法沒有得到在圖G的 生成方法的當前狀態。

  • 如果我不使用發電機的方法和 選擇使用完整列表生成器, 然後我會浪費計算時間 做沒有什麼用處。

解決的辦法是嘗試deepcopy一些特定的生成器方法,但我得到錯誤。

似乎發生器保存對例如G的頂點和邊緣,然後在深度到H時,H中的生成器仍然引用G(這聽起來合乎邏輯)的屬性。

那麼,我是否譴責使用deepcopy畢竟還是不使用生成器方法?

有沒有第三種pythonic方式?

+0

向我們展示一些(僞)代碼,這太抽象了(至少對我而言)。 – orlp

+6

你不能複製生成器,就這麼簡單。所以這個問題對我來說毫無意義。你想做什麼? –

+1

我也不認爲這個問題沒有意義。如果您想複製所有內容,請使用深層複製。如果您不需要複製所有內容,請告訴您不需要複製的內容。 – rafalotufo

回答

2

我很確定我明白你在做什麼。這裏有一個簡單的例子:

class Graph: 
    def __init__(self, nodes): 
     self.nodes = list(nodes) 
     self.nodegen = self.iternodes() 
    def iternodes(self): 
     for node in self.nodes: 
      yield node 
    def copy(self): 
     return Graph(self.nodes) 

G = Graph([1, 2, 3, 4]) 
print G.nodegen.next() 
H = G.copy() 
print H.nodegen.next() 
print G.nodegen.next() 

現在當然會打印出1 1 2。你卻希望H.nodegen記住的G.nodegen的狀態,以便調用H.nodegen.next()打印2.一個簡單的方法是讓他們相同的對象:

class Graph: 
    def __init__(self, nodes, nodegen=None): 
     self.nodes = list(nodes) 
     self.nodegen = self.iternodes() if nodegen is None else nodegen 
    def iternodes(self): 
     for node in self.nodes: 
      yield node 
    def copy(self): 
     return Graph(self.nodes, self.nodegen) 

這將打印1 2 3,因爲調用H.nodegen.next()將提前G.nodegen以及。如果這不是你想要的,似乎沒什麼問題,以保持內部計數器,就像這樣:

class Graph: 
    def __init__(self, nodes, jnode=0): 
     self.nodes = list(nodes) 
     self.nodegen = self.iternodes() 
     self.jnode = jnode 
    def iternodes(self): 
     while self.jnode < len(self.nodes): 
      self.jnode += 1 
      yield self.nodes[self.jnode-1] 
    def copy(self): 
     return Graph(self.nodes, self.jnode) 

這將打印1 2 2,我懷疑是你想要的。當然,當你改變self.nodes時,你必須改變如何處理失效迭代器等事情,但我認爲它應該相當簡單。

+0

嗨@Cosmologicon,是的,這是問題的意義。對我來說,解決方案似乎是使導致問題的迭代器失效,因爲我正在刪除頂點並向圖H添加邊。我使用更復雜的迭代器,例如遍歷圖的三角形和其他特殊的子圖,還有迭代器對於冷凍組合的邊緣。所以如果迭代器保持對頂點和邊的引用,我將陷入困境。 –

+0

我該如何預留或使這種生成器方法無效? –

+0

迭代器本身會失效。這意味着它不應該再被使用。問題是你如何檢測這個並採取適當的步驟來避免使用它。這完全取決於你在第一種情況下如何使用它。在這一點上,我同意你應該發佈一些代碼。 – Cosmologicon