Как скопировать словарь python
Перейти к содержимому

Как скопировать словарь python

  • автор:

Метод dict.copy() в Python, копия словаря

Метод dict.copy() вернет мелкую копию словаря dict .

Смотрите так же модуль copy , что бы сделать глубокую копию словаря, а так же различия между глубокой и неглубокой копией.

Примеры копирования словаря.

>>> x = 'one': 0, 'two': 20, 'three': 3, 'four': 4> >>> y = x.copy() >>> x['one'] = 100 >>> del x['three'] >>> x # >>> y #
  • ОБЗОРНАЯ СТРАНИЦА РАЗДЕЛА
  • Представления словарей dict.keys, dict.values и dict.items
  • Исходный словарь для представления dictview.mapping
  • Получение списка ключей словаря list(dict)
  • Количество элементов в словаре len(dict)
  • Доступ к значению словаря по ключу dict[key]
  • Добавление/изменение значения словаря по ключу key
  • Удаление значения словаря по ключу
  • Проверка наличия/отсутствия ключа key в словаре dict
  • Проверка наличия/отсутствия значения value в словаре Python
  • Проверка наличия/отсутствия пары (key, value) в словаре dict
  • Итерирование по ключам и значениям словаря Python
  • Метод dict.clear(). Очистить словарь
  • Метод dict.copy(), копия словаря
  • Метод dict.fromkeys(), словарь с ключами по умолчанию
  • Метод dict.get(), значение по умолчанию если ключа нет
  • Метод dict.items(), список кортежей
  • Метод dict.keys(), список ключей словаря
  • Метод dict.values(), список значений словаря
  • Метод dict.pop()
  • Метод dict.popitem(), получить пару ключ/значение
  • Метод dict.setdefault(), получает/вставляет значение ключа
  • Метод dict.update(), обновление/дополнение словаря
  • Объединение двух словарей в новый словарь Python
  • Сортировка словаря по значению и/или ключу
  • Обратный порядок/реверс словаря reversed(dict)
  • Генератор словаря и его использование
  • Фильтр словаря по ключам и/или значениям
  • Словарь как фабрика функций

ХОЧУ ПОМОЧЬ
ПРОЕКТУ

Методы словарей и операции над словарями в Python

У класса dict есть классовый метод fromkeys( iterable [, value ]) , с помощью которого создается новый словарь, ключи которого берутся из переданного в метод итерируемого объекта. Значениями всех ключей по-умолчанию является None или передаваемое вторым аргументом значение.

letters = 'aeiyou' nums = [5, 8, 9, 3] words = ('cat', 'dog', 'pig') dl = dict.fromkeys(letters, 0) dn = dict.fromkeys(nums) dw = dn.fromkeys(words, 'gray') print(dl) print(dn) print(dw)

Методы экземпляра словаря keys() , values() , items() возвращают особые типы объектов — dictionary view objects — объекты просмотра словаря. Эти объекты являются итерируемыми.

d = dk = d.keys() dv = d.values() di = d.items() print(dk) print(dv) print(di) for k, v in di: print(k, '=', v) print(list(dk)) print(tuple(dv))
dict_keys(['cat', 'dog', 'pig']) dict_values([5, 3, 1]) dict_items([('cat', 5), ('dog', 3), ('pig', 1)]) cat = 5 dog = 3 pig = 1 ['cat', 'dog', 'pig'] (5, 3, 1)

Важной особенностью экземпляров просмотра словаря является то, что они остаются «связанными» со своим словарем. Поэтому любые изменения последнего отражаются в этих объектах.

d = di = d.items() dv = d.values() print(list(di)) print(sum(list(dv))) d['cow'] = 1 d['pig'] += 1 print(list(di)) print(sum(list(dv)))
[('cat', 5), ('dog', 3), ('pig', 1)] 9 [('cat', 5), ('dog', 3), ('pig', 2), ('cow', 1)] 11

Если подобная связь не требуется, то список всех ключей словаря может быть удобнее получать с помощью встроенной функции list( iterable =()) .

>>> d = >>> k = list(d) >>> k ['cat', 'dog', 'pig'] >>> d['cow'] = 1 >>> k ['cat', 'dog', 'pig']

Если требуется очистить содержимое словаря без удаления самого словаря, следует использовать метод clear() .

d = print(d) print('Number of entries:', len(d)) d.clear() print(d) print('Number of entries:', len(d))
 Number of entries: 3 <> Number of entries: 0

Просто удалить любую запись словаря, обращаясь к ней по ключу, можно с помощью оператора del , который в классе dict перегружается методом __delitem__( self , key ) . Если записи с указанным ключом нет, будет выбрашено исключение KeyError .

>>> a = dict(cat=3, dog=5, pig=1) >>> a >>> del a['cat'] >>> a.__delitem__('pig') >>> a >>> del a['cow'] Traceback (most recent call last): File "", line 1, in KeyError: 'cow'

В отличие от del метод pop( key [, default ]) не только удаляет запись из словаря по ключу, но и возвращает значение этой записи. Если переданного методу ключа нет в словаре, то в качестве значения возвращается default , если он был указан, или выбрасывается KeyError .

d = s = sum(list(d.values())) print(s) # 9 s -= d.pop('dog') print(s) # 6 s -= d.pop('cow', 0) print(s) # 6 s -= d.pop('pig', 0) print(s) # 5

Метод popitem() не принимает аргументов, удаляет из словаря последнюю запись, возвращает ее в виде кортежа, в котором первый элемент представляет собой ключ, второй — значение. Вызов метода на пустой словарь приводит к выбросу KeyError .

d = while len(d) != 0: print(d.popitem())
('pig', 1) ('dog', 3) ('cat', 5)

Метод get( key , default =None) возвращает значение указанного ключа, также как и обычное получение из словаря значения по ключу через квадратные скобки. Однако данный метод никогда не возбуждает KeyError и поэтому может быть предпочтительным в ряде случаев. Значение default возвращается, когда ключа нет в словаре. Вместо None можно указать свое значение.

d = for i in range(4): print(d.get(input('Pet: ')))
Pet: dog 3 Pet: cow None Pet: pig 1 Pet: rabbit None

По аналогии с этим при добавлении записи в словарь вместо нотации d [ key ] = value можно использовать метод setdefault( key , default =None) . Его отличительной особенностью является то, что если запись с таким ключом уже есть в словаре, ее значение не будет перезаписано. При этом метод возвращает значение ключа, по которому можно оценить, была ли добавлена новая запись, или она уже ранее присутствовала в словаре.

d = n = d.setdefault('cow', 1) print(n) n = d.setdefault('dog', 1) print(n) print(d)

Наличие записи в словаре можно проверить с помощью оператора in .

d = print('cat' in d) # True print('cat' not in d) # False print('cow' in d) # False print('cow' not in d) # True

При присваивании другой переменной словарь не копируется, а создается вторая ссылка на него. Поэтому, чтобы скопировать словарь, следует использовать метод copy() .

>>> first = >>> second = first >>> third = first.copy() >>> >>> second['c'] = 4 >>> >>> first >>> second >>> third >>> >>> id(first) == id(second) True >>> id(first) == id(third) False

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

>>> first = >>> second = first.copy() >>> >>> first['bread'][1] += 0.75 >>> first['milk'] = [6, 58] >>> >>> first >>> second

С помощью метода update([ other ]) можно объединить два словаря в один или, используя итерируемый объект, добавить в словарь новые записи или обновить значения существующих. При совпадении ключей значения словаря, к которому применяется метод, перезаписываются на новые.

d = print(d) d.update() d.update([('rabbit', 4), ('sheep', 2)]) d.update(hen=8, cat=3, pig=5) print(d)

Как из одного словаря, скопировать значение в другой словарь, со вложенным словарем?

Перечитал много про вложенные словари, но в итоге даже не могу даже распечатать вложенные словари через цикл из a_dict, чтобы заменить value .

for t in a_dict["tests"]: print(("<> "*len(t)).format(t.get('id'), t.get("value"), t.get('title'), t.get('values'))) 

Подскажите в какую сторону копать. Ощущение, что я что-то упускаю, и будет в итоге что-то типа:

for i in range(len(b_dict['values'])): if a_dict[id] == b_dict[id]: a_dict['tests'][i]['value'] = b_dict['values'][i]['value'] 

Только так меняется только одно значение, а как добраться до остальных value в a_dict , если они так неравномерно вложены?

id в a_dict перебором находятся так:

print(a_dict["tests"][0]['id']) # 2 print(a_dict["tests"][1]['id']) # 41 print(a_dict["tests"][2]['id']) # 73 print(a_dict["tests"][2]["values"][0]['id']) # 345 print(a_dict["tests"][2]["values"][0]["values"][0]['id']) # 230 print(a_dict["tests"][2]["values"][0]["values"][0]["values"][0]['id']) # 234 print(a_dict["tests"][2]["values"][0]["values"][0]["values"][1]['id']) # 653 print(a_dict["tests"][2]["values"][1]['id']) # 110 print(a_dict["tests"][2]["values"][1]["values"][0]['id']) # 261 print(a_dict["tests"][2]["values"][1]["values"][0]["values"][0]['id']) # 238 print(a_dict["tests"][2]["values"][1]["values"][0]["values"][1]['id']) # 690 print(a_dict["tests"][3]['id']) # 122 print(a_dict["tests"][3]["values"][0]['id']) # 5321 print(a_dict["tests"][3]["values"][1]['id']) # 5322 

Метод dict.copy() в Python

Метод dict.copy() в Python возвращает неглубокую копию словаря.

dict.copy()

Метод copy() не принимает никаких параметров.

Возвращаемое значение

Этот метод возвращает мелкую копию словаря. Он не изменяет исходный словарь.

Пример 1: Как работает копирование для словарей?

original = new = original.copy() print('Orignal: ', original) print('New: ', new)

Orignal: New:

Разница в использовании метода copy() и оператора = для копирования словарей

Когда используется метод copy(), создается новый словарь, который заполняется копией ссылок из исходного словаря.

Когда используется оператор =, создается новая ссылка на исходный словарь.

Пример 2: Использование оператора =

original = new = original # removing all elements from the list new.clear() print('new: ', new) print('original: ', original)
new: <> original: <>

Здесь, когда очищается новый словарь, очищается и исходный словарь.

Пример 3: использование copy()

original = new = original.copy() # removing all elements from the list new.clear() print('new: ', new) print('original: ', original)

new: <> original:

Здесь, когда новый словарь очищается, исходный словарь остается без изменений.

Python никогда не копирует объекты неявно. Когда вы устанавливаете dict2 = dict1, вы заставляете их ссылаться на один и тот же точный объект dict, поэтому, когда вы изменяете его, все ссылки на него продолжают ссылаться на объект в его текущем состоянии. Если вы хотите скопировать dict (что бывает редко), вы должны сделать это явно с помощью
dict2 = dict(dict1)

или так
dict2 = dict1.copy()
Когда вы назначаете dict2 = dict1, вы не делаете копию dict1, это приводит к тому, что dict2 является просто другим именем для dict1.

Чтобы скопировать изменяемые типы, такие как словари, используйте deepcopy модуля копирования.
import copy
dict2 = copy.deepcopy(dict1)
Подробнее можно прочитать в справке https://docs.python.org/3.6/library/copy.html
В дополнение к другим предоставленным решениям вы можете использовать ** для интеграции словаря в пустой словарь, например,

Теперь у вас будет «неглубокая» или как ее еще называют shallow копия other_dict.
Разница между неглубоким и глубоким копированием актуальна только для составных объектов (объектов, содержащих другие объекты, такие как списки или экземпляры классов):

Неглубокая копия создает новый составной объект, а затем (насколько это возможно) вставляет в него ссылки на объекты, найденные в оригинале.

Глубокая копия создает новый составной объект, а затем рекурсивно вставляет в него копии объектов, найденных в оригинале.
>>> import copy
>>> dict1 = >
>>> dict2 = dict1.copy()
>>> dict2
>
>>> dict2[«key2»][«mutable»] = False
>>> dict2
>
>>> dict1
>
>>> id(dict1)
140641197660704
>>> id(dict2)
140641196407832
>>> id(dict1[«key2»])
140641176198960
>>> id(dict2[«key2»])
140641176198960
Даже если мы применили copy для dict1, значение mutable изменяется на false как для dict2, так и для dict1, хотя мы меняем его только на dict2. Это происходит потому, что мы изменили значение изменяемой части dict в dict1. Когда мы применяем копию на dict, она будет делать только неглубокую копию, что означает, что она копирует все неизменяемые значения в новый dict и не копирует изменяемые значения, но будет ссылаться на них.

Конечное решение состоит в том, чтобы сделать глубокую копию dict1, чтобы полностью создать новый dict со всеми скопированными значениями, включая изменяемые значения.
>>>import copy
>>> dict1 = >
>>> dict2 = copy.deepcopy(dict1)
>>> dict2
>
>>> id(dict1)
140641196228824
>>> id(dict2)
140641197662072
>>> id(dict1[«key2»])
140641178056312
>>> id(dict2[«key2»])
140641197662000
>>> dict2[«key2»][«mutable»] = False
>>> dict2
>
>>> dict1
>
Идентификаторы разные, это означает, что dict2 — это совершенно новый dict со всеми значениями в dict1.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *