Есть много хороших ответов, но я хочу подчеркнуть одну вещь.
Вы можете использовать как dict.pop()
метод, так и более общий del
оператор для удаления элементов из словаря. Они оба видоизменяют оригинальный словарь, поэтому вам нужно сделать копию (см. Подробности ниже).
И они оба выдают a, 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}