2009-05-08 20 views
19

mi chiedevo a come funziona esattamente deepcopy nel contesto seguente:dizionario Python deepcopy

from copy import deepcopy 

def copyExample: 
    self.myDict = {} 
    firstPosition = "First" 
    firstPositionContent = ["first", "primero"] 
    secondPosition = "Second" 
    secondPositionContent = ["second"] 
    self.myDict[firstPosition] = firstPositionContent 
    self.myDict[secondPosition] = secondPositionContent 
    return deepcopy(self.myDict) 

def addExample(self): 
    copy = self.copyExample() 
    copy["Second"].add("segundo") 

lo fa tornare il riferimento alle liste che ho nel dizionario? Oppure funziona come mi aspetto e copio ogni lista in una nuova lista con un riferimento diverso?

So che cos'è una copia profonda (quindi non c'è bisogno di spiegare la differenza tra profondità e profondità), ma mi chiedo se funzioni come mi aspetto che faccia e quindi non cambio la variabile di istanza quando uso addExample().

+1

Hai stampare i due dizionari per vedere se sono diversi? Che cosa hai visto? Erano diversi? Se è così, la copia ha una nuova lista a cui hai aggiunto un elemento. –

risposta

15

Il documentation rende abbastanza chiaro che stai ricevendo nuove copie, non riferimenti. Deepcopy crea copie approfondite per tipi incorporati, con diverse eccezioni e che è possibile aggiungere operazioni di copia personalizzate agli oggetti definiti dall'utente per ottenere anche il supporto di copie avanzate. Se non sei sicuro, questo è il test unitario.

+0

Non penso che sia stato costruito nei tipi, afferma che "copia" gli oggetti selezionabili ... Vuol dire che otterrei un nuovo elenco di riferimento? – mandel

+7

Deepcopy ha un breve elenco di eccezioni. Tutto il resto è copiato. "Questo modulo non copia tipi come modulo, metodo, traccia stack, stack frame, file, socket, finestra, array o tipi simili." Ottieni una nuova lista. Non un riferimento alla lista ma una nuova lista. Stampa i due dizionari dell'esempio e guardali. –

2

So che non sta rispondendo alla tua domanda, ma penso che sia degno di nota per le persone che stanno guardando questa domanda.

Se i dati che si stanno copiando sono di natura semplice, deepcopy potrebbe essere eccessivo. Con la natura semplice intendo se i tuoi dati sono rappresentabili come Json. Lasciatemi illustrare con il codice:

Ho utilizzato http://www.json-generator.com/ per ottenere alcuni dati JSON campione.

def deepCopyList(inp): 
    for vl in inp: 
     if isinstance(vl, list): 
      yield list(deepCopyList(vl)) 
     elif isinstance(vl, dict): 
      yield deepCopyDict(vl) 

def deepCopyDict(inp): 
    outp = inp.copy() 
    for ky, vl in outp.iteritems(): 
     if isinstance(vl, dict): 
      outp[ky] = deepCopyDict(vl)  
     elif isinstance(vl, list): 
      outp[ky] = list(deepCopyList(vl)) 
    return outp 

def simpleDeepCopy(inp): 
    if isinstance(inp, dict): 
     return deepCopyDict(inp) 
    elif isinstance(inp, list): 
     return deepCopyList(inp) 
    else: 
     return inp 

if __name__ == '__main__': 
    import simplejson as json 
    import time 
    from copy import deepcopy 
    fl = open('sample.json', 'r') 
    sample = json.load(fl) 
    start = time.time() 
    for _ in xrange(10000): 
     tmp = simpleDeepCopy(sample) 
    end = time.time() 
    print 'simpleDeepCopy: ' + str(end - start) 
    start = time.time() 
    for _ in xrange(10000): 
     tmp = deepcopy(sample) 
    end = time.time() 
    print 'copy.deepcopy: ' + str(end - start) 

uscita:

simpleDeepCopy: 0.0132050514221 
copy.deepcopy: 2.66142916679 

simpleDeepCopy: 0.0128579139709 
copy.deepcopy: 2.60736298561 
+0

"Con natura semplice intendo se i tuoi dati sono rappresentabili come Json" - questa è un'affermazione errata: anche qualche semplice oggetto "JSON-capable" potrebbe avere bisogno di '.deepcopy()' per evitare riferimenti. Prova questo: 'a = {1: 'A', 2: ['a', 'b', 'c'], 3: 'Z'}; b = a.copy(); a [2] .Append ('d'); print b' – MestreLion

+0

Se i dati sono rappresentabili come JSON, perché non usare semplicemente 'json.loads (json.dumps (data))' ..? – rob