Мутация словаря Python [дубликат]

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(''));
325
задан user225312 20 October 2010 в 07:51
поделиться

7 ответов

Под «мелким копированием» это означает, что контент словаря не копируется по значению, а просто создается новая ссылка.

>>> 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]})

Итак:

  1. b = a: присвоение задания, сделать a и b указывает на тот же объект , Illustration of 'a = b': 'a' and 'b' both point to '{1: L}', 'L' points to '[1, 2, 3]'. [/g1]
  2. b = a.copy(): Неверное копирование, a и b станут двумя изолированными объектами, но их содержимое по-прежнему имеет одну и ту же ссылку Illustration of 'b = a.copy()': 'a' points to '{1: L}', 'b' points to '{1: M}', 'L' and 'M' both point to '[1, 2, 3]'. [/g2]
  3. b = copy.deepcopy(a): Глубокое копирование, структура и содержание a и b становятся полностью изолированными. Illustration of 'b = copy.deepcopy(a)': 'a' points to '{1: L}', 'L' points to '[1, 2, 3]'; 'b' points to '{1: M}', 'M' points to a different instance of '[1, 2, 3]'. [/g3]
807
ответ дан kennytm 18 August 2018 в 18:43
поделиться
  • 1
    Хороший ответ, но вы можете рассмотреть возможность исправления грамматической ошибки в своем первом предложении. И нет причин не использовать L снова в b. Это упростит пример. – Tom Russell 27 October 2017 в 04:47
  • 2
    @kennytm: В чем разница между первыми двумя примерами? Вы получаете тот же результат, но немного отличаетесь внутренней реализацией, но для чего это важно? – JavaSa 20 January 2018 в 12:53
  • 3
    @TomRussell: Или кто-нибудь, так как этот вопрос довольно старый, мой вопрос уточнения для всех – JavaSa 20 January 2018 в 12:58
  • 4
    @JavaSa Это важно, если, скажем, вы b[1][0] = 5. Если b является мелкой копией, вы только что изменили a[1][0]. – Tom Russell 20 January 2018 в 22:11
  • 5
    Великое объяснение, ... действительно спас мой день! Спасибо ... Может ли это быть применено к списку, str и другим типам данных python? – Bhuro 19 February 2018 в 14:38

Возьмем этот пример:

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
23
ответ дан eumiro 18 August 2018 в 18:43
поделиться
  • 1
    no change in original, since ['a'] is an immutable integer Это. На самом деле он отвечает на заданный вопрос. – CivFan 14 April 2015 в 18:08

«new» и «original» - разные dicts, поэтому вы можете обновить только один из них. Элементы неточно скопированы, а не сам dict.

4
ответ дан Joril 18 August 2018 в 18:43
поделиться

Содержание неточно скопировано.

Итак, если исходный dict содержит list или другой dictionary, изменяя один из них в оригинале или его мелкой копии изменят их (list или dict) в другом.

1
ответ дан Jungle Hunter 18 August 2018 в 18:43
поделиться

Это не вопрос глубокой копии или мелкой копии, ни одно из того, что вы делаете, - это глубокая копия.

Здесь:

>>> new = original 

вы создаете новую ссылку на список / dict, на которые ссылается оригинал.

, а здесь:

>>> new = original.copy()
>>> # or
>>> new = list(original) # dict(original)

вы создаете новый список / dict, который заполнен копией ссылок объекты, содержащиеся в исходном контейнере.

35
ответ дан Lie Ryan 18 August 2018 в 18:43
поделиться

В вашей второй части вы должны использовать new = original.copy()

.copy, а = - разные вещи.

0
ответ дан Stephen Rauch 18 August 2018 в 18:43
поделиться

Добавление к ответу Кеннетма. Когда вы делаете мелкую копию 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 - это новый словарь со значениями, относящимися к значениям родителя

4
ответ дан Vkreddy Komatireddy 18 August 2018 в 18:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: