Комментарии 11
Ключами могут выступать следующие типы данных: строки, числа (целые и дробные), кортежи.
А ещё, например, frozenset
P.S. Насколько понимаю, ключом может быть любой неизменяемый тип.
Если я правильно помню, чтобы объект мог быть ключом, достаточно, чтобы для него было определено хэшерование и сравнение на эквивалентность.
Причём, для корректной работы подразумевается, что и первое, и второе должны давать одинаковый результат на протяжении всего срока жизни объекта.
То есть, объект вполне может быть ключом словаря, и при этом иметь внутри себя какие-то изменяемые поля - при условии, что эти поля не влияют на подсчёт хэша и проверку на эквивалентность.
Словарь в языке Python — неупорядоченная структура данных
Это смотря что понимать под упорядоченностью
Dictionaries preserve insertion order. Note that updating a key does not affect the order. Keys added after deletion are inserted at the end.
Changed in version 3.7: Dictionary order is guaranteed to be insertion order.
Если запустить несколько раз нижеприведённый код (Python 3.7+), можно убедиться, что элементы словаря всегда выводятся в одном и том же порядке, в отличие от элементов множества:
d = {1: "1", 2: "2"}
s = {"1", "2"}
print(d, s, sep='\n')
d[3] = "3"
s.add("0")
print(d, s, sep='\n')
Но это особенность конкретной реализации. В целом спецификация языка не гарантирует какого-либо порядка.
Словарь (dictionary или dict) — это неупорядоченная (в отличие от списка)
Расходимся. Словари, кажется, с версии 3.6 упорядочены, после того, как их внутреннее устройство поменяли.
Про dict.pop() и dict.popitem()
Упустили важный момент - эти функции не просто удаляют элемент, но и возвращают его значение.
То есть можно делать так:
x = data.pop(key)
# Делаем что-то с x
Уровень сложности материала: Средний
Спасибо за 3 минуты потраченного времени на пролистывание этого материала чуть проще чем «Простой»
При копировании через copy(), следует учесть, что если значением элемента словаря будет изменяемый объект, то модификация копии словаря повлечёт изменение значения в оригинале.
пример:
import copy
dict_orig = {"a": [1, 2, [8, 8, 8], 3, 4]}
dict_copy = dict_orig.copy()
print(dict_orig)
# {'a': [1, 2, [8, 8, 8], 3, 4]}
print(dict_copy)
#{'a': [1, 2, [8, 8, 8], 3, 4]}
# в копии словаря добавляем значение в список
dict_copy["a"][2].append("xxx")
print(dict_orig)
#{'a': [1, 2, [8, 8, 8, 'xxx'], 3, 4]}
print(dict_copy)
#{'a': [1, 2, [8, 8, 8, 'xxx'], 3, 4]}
# изменение повлияло и на оригинал
#используя deepcopy:
x_dict_orig = {"a": [1, 2, [8, 8, 8], 3, 4]}
x_dict_copy = copy.deepcopy(x_dict_orig)
print(x_dict_orig)
#{'a': [1, 2, [8, 8, 8], 3, 4]}
print(x_dict_copy)
#{'a': [1, 2, [8, 8, 8], 3, 4]}
# в копии словаря добавляем значение в список
x_dict_copy["a"][2].append("xxx")
print(x_dict_orig)
#{'a': [1, 2, [8, 8, 8], 3, 4]}
print(x_dict_copy)
#{'a': [1, 2, [8, 8, 8, 'xxx'], 3, 4]}
# оригинал не изменился
для безопасного копирования лучше использовать функцию deepcopy модуля copy
Для этого нужно подготовить два списка и несколько усложнить базовую запись генератора
Я бы еще добавил, что есть несколько более лаконичный способ аналогично создать словарь с использованием zip()
без явного использования генератора словаря:team_names = ["Александр", "Виктория", "Евгений", "Петр", "Денис"]
team_numbers = [23, 43, 26, 52, 32]
# team_ages = {name : age for name, age in zip(team_names,team_numbers)} # используем вспомогательную функцию zip() для итерирования сразу двух листов
team_ages = dict(zip(team_names, team_numbers))
print(team_ages)
Словари в Python: обзор и как пользоваться