var str = "IAMA JavaScript Developer";
var a=str.split(''), b = a.length;
for (var i=0; i<b; i++) {
a.unshift(a.splice(1+i,1).shift())
}
a.shift();
alert(a.join(''));
Под «мелким копированием» это означает, что контент словаря не копируется по значению, а просто создается новая ссылка.
>>> a = {1: [1,2,3]}
>>> b = a.copy()
>>> a, b
({1: [1, 2, 3]}, {1: [1, 2, 3]})
>>> a[1].append(4)
>>> a, b
({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]})
Напротив, глубокий копия будет копировать все содержимое по значению.
>>> import copy
>>> c = copy.deepcopy(a)
>>> a, c
({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]})
>>> a[1].append(5)
>>> a, c
({1: [1, 2, 3, 4, 5]}, {1: [1, 2, 3, 4]})
Итак:
b = a
: присвоение задания, сделать a
и b
указывает на тот же объект , [/g1] b = a.copy()
: Неверное копирование, a
и b
станут двумя изолированными объектами, но их содержимое по-прежнему имеет одну и ту же ссылку [/g2] b = copy.deepcopy(a)
: Глубокое копирование, структура и содержание a
и b
становятся полностью изолированными. [/g3] Возьмем этот пример:
original = dict(a=1, b=2, c=dict(d=4, e=5))
new = original.copy()
Теперь давайте изменим значение на уровне «мелкий» (первый):
new['a'] = 10
# new = {'a': 10, 'b': 2, 'c': {'d': 4, 'e': 5}}
# original = {'a': 1, 'b': 2, 'c': {'d': 4, 'e': 5}}
# no change in original, since ['a'] is an immutable integer
Теперь давайте изменим значение на один уровень глубже :
new['c']['d'] = 40
# new = {'a': 10, 'b': 2, 'c': {'d': 40, 'e': 5}}
# original = {'a': 1, 'b': 2, 'c': {'d': 40, 'e': 5}}
# new['c'] points to the same original['d'] mutable dictionary, so it will be changed
no change in original, since ['a'] is an immutable integer
Это. На самом деле он отвечает на заданный вопрос.
– CivFan
14 April 2015 в 18:08
«new» и «original» - разные dicts, поэтому вы можете обновить только один из них. Элементы неточно скопированы, а не сам dict.
Содержание неточно скопировано.
Итак, если исходный dict
содержит list
или другой dictionary
, изменяя один из них в оригинале или его мелкой копии изменят их (list
или dict
) в другом.
Это не вопрос глубокой копии или мелкой копии, ни одно из того, что вы делаете, - это глубокая копия.
Здесь:
>>> new = original
вы создаете новую ссылку на список / dict, на которые ссылается оригинал.
, а здесь:
>>> new = original.copy()
>>> # or
>>> new = list(original) # dict(original)
вы создаете новый список / dict, который заполнен копией ссылок объекты, содержащиеся в исходном контейнере.
В вашей второй части вы должны использовать new = original.copy()
.copy
, а =
- разные вещи.
Добавление к ответу Кеннетма. Когда вы делаете мелкую копию parent.copy () , создается новый словарь с одинаковыми ключами, но значения не копируются, на которые они ссылаются. Если вы добавите новое значение в parent_copy он не будет влиять на parent , поскольку parent_copy является новым словарем, а не ссылкой.
parent = {1: [1,2,3]}
parent_copy = parent.copy()
parent_reference = parent
print id(parent),id(parent_copy),id(parent_reference)
#140690938288400 140690938290536 140690938288400
print id(parent[1]),id(parent_copy[1]),id(parent_reference[1])
#140690938137128 140690938137128 140690938137128
parent_copy[1].append(4)
parent_copy[2] = ['new']
print parent, parent_copy, parent_reference
#{1: [1, 2, 3, 4]} {1: [1, 2, 3, 4], 2: ['new']} {1: [1, 2, 3, 4]}
Значение хэша (id) ] parent [1] , parent_copy [1] идентичны, что подразумевает [1,2,3] родителя [1] и parent_copy [ 1] , хранящийся при идентификаторе 140690938288400.
Но хэш из родительского родителя и parent_copy отличается тем, что подразумевается, что это разные словари и parent_copy - это новый словарь со значениями, относящимися к значениям родителя
L
снова вb
. Это упростит пример. – Tom Russell 27 October 2017 в 04:47b[1][0] = 5
. Еслиb
является мелкой копией, вы только что изменилиa[1][0]
. – Tom Russell 20 January 2018 в 22:11