Есть много хороших ответов, но я хочу подчеркнуть одну вещь.
Вы можете использовать как dict.pop()
метод, так и более общий del
оператор для удаления элементов из словаря.Они оба видоизменяют исходный словарь, поэтому вам нужно сделать копию (см. Подробности ниже).
И оба они поднимут KeyError
, если вы нажмете клавишу 'их предоставление отсутствует в словаре:
key_to_remove = "c"
d = {"a": 1, "b": 2}
del d[key_to_remove] # Raises `KeyError: 'c'`
и
key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove) # Raises `KeyError: 'c'`
Вы должны позаботиться об этом:
захватывая исключение:
key_to_remove = "c"
d = {"a": 1, "b": 2}
try:
del d[key_to_remove]
except KeyError as ex:
print("No such key: '%s'" % ex.message)
и
key_to_remove = "c"
d = {"a": 1, "b": 2}
try:
d.pop(key_to_remove)
except KeyError as ex:
print("No such key: '%s'" % ex.message)
путем выполнения проверки:
key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
del d[key_to_remove]
и
key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
d.pop(key_to_remove)
, но с pop()
есть также гораздо более краткий способ - укажите возвращаемое значение по умолчанию:
key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove, None) # No `KeyError` here
Если вы не используете pop()
, чтобы получитьЗначение удаляемого ключа вы можете указать, не обязательно None
.Хотя может случиться так, что использование del
с in
проверкой будет немного быстрее из-за того, что pop()
является функцией со своими собственными сложностями, вызывающими накладные расходы.Обычно это не так, поэтому pop()
со значением по умолчанию достаточно.
Что касается основного вопроса, вам придется сделать копию своего словаря, чтобы сохранить исходный словарь иесть новый без удаления ключа.
Некоторые другие люди здесь предлагают сделать полную (глубокую) копию с copy.deepcopy()
, что может быть избыточным, «нормальным» (мелкой) копии, используя copy.copy()
или dict.copy()
, может быть достаточно.Словарь хранит ссылку на объект в качестве значения для ключа.Поэтому, когда вы удаляете ключ из словаря, эта ссылка удаляется, а не объект, на который ссылаются.Сам объект может быть впоследствии удален сборщиком мусора автоматически, если в памяти нет других ссылок на него.Для создания глубокой копии требуется больше вычислений по сравнению с мелкой копией, поэтому она снижает производительность кода, делая копию, тратя память и предоставляя больше работы ГХ, иногда достаточно мелкой копии.
Однако, если у вас изменяемая копияобъекты в качестве значений словаря и планируете изменить их позже в возвращенном словаре без ключа, вам нужно сделать глубокую копию.
С мелкой копией:
def get_dict_wo_key(dictionary, key):
"""Returns a **shallow** copy of the dictionary without a key."""
_dict = dictionary.copy()
_dict.pop(key, None)
return _dict
d = {"a": [1, 2, 3], "b": 2, "c": 3}
key_to_remove = "c"
new_d = get_dict_wo_key(d, key_to_remove)
print(d) # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3], "b": 2}
new_d["a"].append(100)
print(d) # {"a": [1, 2, 3, 100], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3, 100], "b": 2}
new_d["b"] = 2222
print(d) # {"a": [1, 2, 3, 100], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3, 100], "b": 2222}
С глубокой копией:
from copy import deepcopy
def get_dict_wo_key(dictionary, key):
"""Returns a **deep** copy of the dictionary without a key."""
_dict = deepcopy(dictionary)
_dict.pop(key, None)
return _dict
d = {"a": [1, 2, 3], "b": 2, "c": 3}
key_to_remove = "c"
new_d = get_dict_wo_key(d, key_to_remove)
print(d) # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3], "b": 2}
new_d["a"].append(100)
print(d) # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3, 100], "b": 2}
new_d["b"] = 2222
print(d) # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d) # {"a": [1, 2, 3, 100], "b": 2222}