2015-07-29 5 views
0

Я ищу решение, чтобы избежать deepcopy() в моей задаче с помощью Python.Избегайте deepcopy() в Python при смене словаря

Я реализую анализатор статистической зависимости, используя алгоритм chu-liu-edmonds. У меня есть график, представленный как словарь с каждым головным узлом, хранящимся в виде ключа, причем каждый из них имеет список, содержащий один или несколько объектов дуги класса в качестве значения.

В алгоритме cle, мне нужно изменить график (сжимать цикл). Это означает, что мне нужно удалить объекты дуги и головы и добавить другие, в то время как позже мне понадобится исходный граф для расширения этих сокращенных циклов. Прямо сейчас, я достигаю этого, глубоко копируя исходный граф и передавая его в контрактную функцию.

Теперь я запускал свою программу с помощью cProfile и выяснил, что все, что связано с deepcopy, на сегодняшний день является частью алгоритма, который занимает больше всего времени.

Так что мой вопрос: есть ли способ избежать/уменьшить это в моей ситуации?

+0

Если изменения, которые вы делаете во время сокращения, должны быть выполнены на месте, и вы должны сохранить исходный график, я не думаю, что можно предотвратить необходимость в копировании второй копии графика, загрузив его дважды начать или сделать глубокую копию. Возможно ли построить сокращенный график в виде нового графика при прохождении процесса или в противном случае хранить информацию, необходимую для преобразования, если это необходимо, вместо того, чтобы фактически хранить сжатый граф? – dmargol1

+0

Как я думаю об этом, это может быть лучший способ попытаться построить новый, а не копировать старый и изменить его. Это на самом деле никогда не происходило со мной. Благодаря! –

ответ

0

Как @ dmargol1 предложил в комментариях, Я смог избежать deepcopy() и copy(), вместо этого построив график с нуля, вместо того, чтобы копировать и изменять его, что было на самом деле намного быстрее.

Если это возможно: сделайте это!

Если копирование необходимо, есть два способа. Если вам не нужно изменять значения, copy() - это путь, потому что он намного быстрее, чем deepcopy() (см. Комментарий @ george-solymosi). Если требуется изменить значения, то метод deepcopy - единственный способ (см. Комментарий @gall).

1

UPDATE: Если вы хотите изменить списки в Словаре вы не можете избежать DeepCopy() но вы должны сделать следующее:

«Сохранить» только значение изменяемых/нестираемых элементов (т.е. списки) графика, неполный график. Затем сделайте необходимую модификацию на dict/graph, затем вы можете использовать «сохраненные» элементы для дальнейшей модификации графика.

Использование dict.copy(), как вы можете видеть ниже на d.copy() является 100000x s быстрее:

from copy import deepcopy 
from time import time 

# with simply assignment ------------- 

d = {"a":[x for x in range(1000000)]} 

t = time() 
e = d 
print 'elapsed time with standard assignment:', time()-t 

e["b"] = [1,2,3] 
del e["a"] 
print d.keys() 

# with deepcopy() -------------------- 

d = {"a":[x for x in range(1000000)]} 

t = time() 
e = deepcopy(d) 
print '\nelapsed time with deepcopy():', time()-t 

e["b"] = [1,2,3] 
del e["a"] 
print d.keys() 

# with d.copy() --------------------- 

d = {"a":[x for x in range(1000000)]} 

t = time() 
e = d.copy() 
print '\nelapsed time with d.copy():', time()-t 

e["b"] = [1,2,3] 
del e["a"] 
print d.keys() 

Выход:

elapsed time with standard assignment: 0.000110149383545 
['b'] 

elapsed time with deepcopy(): 1.78457307816 
['a'] 

elapsed time with d.copy(): 2.09808349609e-05 
['a'] 
+0

Но '' dict.copy() '' делает мелкую копию, которая не является желаемым поведением в этом случае вложенной структуры. – Gall

+0

@Gall Как вы можете видеть из вывода моего примера 'dict.copy()' делает работу именно то, что нам нужно. то естьбудущая модификация ** не изменяет ** ** оригинальный ** словарь, таким образом делает ту же работу, что мы ожидаем от 'deepcopy()'. – Geeocode

+0

Если вам не нужно изменять значение списка да, в противном случае нет. – Gall

Смежные вопросы