Há muitas respostas legais, mas quero enfatizar uma coisa.
Você pode usar o dict.pop()
método e uma del
instrução mais genérica para remover itens de um dicionário. Ambos mudam o dicionário original, então você precisa fazer uma cópia (veja detalhes abaixo).
E os dois irão gerar um KeyError
se a chave que você está fornecendo a eles não estiver presente no dicionário:
key_to_remove = "c"
d = {"a": 1, "b": 2}
del d[key_to_remove] # Raises `KeyError: 'c'`
e
key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove) # Raises `KeyError: 'c'`
Você tem que cuidar disso:
capturando a exceção:
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)
e
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)
executando uma verificação:
key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
del d[key_to_remove]
e
key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
d.pop(key_to_remove)
mas pop()
também há uma maneira muito mais concisa - forneça o valor de retorno padrão:
key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove, None) # No `KeyError` here
A menos que você use pop()
para obter o valor de uma chave sendo removida, você pode fornecer qualquer coisa, não necessário None
. Embora possa ser que o uso del
com in
cheque seja um pouco mais rápido devido a pop()
uma função com suas próprias complicações causando sobrecarga. Normalmente não é o caso, portanto, pop()
com o valor padrão é bom o suficiente.
Quanto à pergunta principal, você terá que fazer uma cópia do seu dicionário, salvar o dicionário original e ter um novo sem a chave ser removida.
Algumas outras pessoas aqui sugerem fazer uma cópia completa (profunda) com copy.deepcopy()
, que pode ser um exagero, uma cópia "normal" (superficial), usando copy.copy()
ou dict.copy()
, pode ser suficiente. O dicionário mantém uma referência ao objeto como um valor para uma chave. Portanto, quando você remove uma chave de um dicionário, essa referência é removida, não o objeto que está sendo referenciado. O próprio objeto pode ser removido posteriormente automaticamente pelo coletor de lixo, se não houver outras referências para ele na memória. Fazer uma cópia profunda requer mais cálculos em comparação com a cópia superficial; portanto, diminui o desempenho do código ao fazer a cópia, desperdiçando memória e fornecendo mais trabalho ao GC; às vezes, a cópia superficial é suficiente.
No entanto, se você tiver objetos mutáveis como valores do dicionário e planeja modificá-los posteriormente no dicionário retornado sem a chave, precisará fazer uma cópia profunda.
Com cópia rasa:
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}
Com cópia profunda:
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}