Python словарь Deepcopy - PullRequest
       10

Python словарь Deepcopy

20 голосов
/ 08 мая 2009

Мне было интересно, как именно работает глубокая копия в следующем контексте:

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")

Возвращает ли это ссылку на списки, которые у меня есть в словаре? Или это работает так, как я ожидал, и скопировал каждый список в новый список с другой ссылкой?

Я знаю, что такое глубокая копия (поэтому нет необходимости объяснять разницу между глубокой и мелкой копией), но мне интересно, работает ли она так, как я ожидаю, и поэтому не меняю переменную экземпляра при использовании 1006 *.

Ответы [ 2 ]

15 голосов
/ 08 мая 2009

Документация ясно показывает, что вы получаете новые копии, а не ссылки. Deepcopy создает глубокие копии для встроенных типов, с различными исключениями, и вы можете добавлять настраиваемые операции копирования к вашим пользовательским объектам, чтобы также получить поддержку для глубокого копирования. Если вы не уверены, для этого и есть модульное тестирование.

2 голосов
/ 20 февраля 2014

Я знаю, что это не отвечает на ваш вопрос, но я думаю, что это примечательно для людей, которые смотрят на этот вопрос.

Если данные, которые вы копируете, просты по своей природе, глубокое копирование может оказаться излишним. Я имею в виду простой характер, если ваши данные представимы в виде Json. Позвольте мне проиллюстрировать с кодом:

Я использовал http://www.json -generator.com / , чтобы получить пример данных JSON.

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)

выход:

simpleDeepCopy: 0.0132050514221
copy.deepcopy: 2.66142916679

simpleDeepCopy: 0.0128579139709
copy.deepcopy: 2.60736298561
...