Jest wiele fajnych odpowiedzi, ale chcę podkreślić jedną rzecz.
Możesz użyć zarówno dict.pop()metody, jak i bardziej ogólnej delinstrukcji, aby usunąć elementy ze słownika. Obaj mutują oryginalny słownik, więc musisz zrobić kopię (zobacz szczegóły poniżej).
I oba podniosą, KeyErrorjeśli klucz, który im podajesz, nie jest obecny w słowniku:
key_to_remove = "c"
d = {"a": 1, "b": 2}
del d[key_to_remove] # Raises `KeyError: 'c'`
i
key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove) # Raises `KeyError: 'c'`
Musisz się tym zająć:
przechwytując wyjątek:
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)
i
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)
poprzez sprawdzenie:
key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
del d[key_to_remove]
i
key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
d.pop(key_to_remove)
ale pop()jest też o wiele bardziej zwięzły sposób - podaj domyślną wartość zwracaną:
key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove, None) # No `KeyError` here
O ile nie użyjesz go pop()do odzyskania wartości klucza, możesz podać wszystko, co nie jest konieczne None. Chociaż może się zdarzyć, że używanie delz inkontrolą jest nieco szybsze, ponieważ pop()jest funkcją z własnymi komplikacjami powodującymi narzut. Zwykle tak nie jest, więc pop()przy domyślnej wartości jest wystarczająco dobra.
Jeśli chodzi o główne pytanie, będziesz musiał zrobić kopię swojego słownika, aby zapisać oryginalny słownik i mieć nowy bez wyjmowania klucza.
Niektórzy inni ludzie sugerują tutaj wykonanie pełnej (głębokiej) kopii copy.deepcopy(), która może być przesadą, „normalną” (płytką) kopią, używając copy.copy()lub dict.copy(), może wystarczyć. Słownik przechowuje odwołanie do obiektu jako wartość klucza. Kiedy więc usuniesz klucz ze słownika, odwołanie to zostanie usunięte, a nie odwołany do obiektu. Sam obiekt może zostać później automatycznie usunięty przez moduł wyrzucający elementy bezużyteczne, jeśli nie ma w nim innych odniesień. Wykonywanie głębokiej kopii wymaga więcej obliczeń w porównaniu z płytką kopią, więc zmniejsza wydajność kodu, tworząc kopię, marnując pamięć i zapewniając więcej pracy GC, czasami płytka kopia wystarcza.
Jeśli jednak masz zmienne obiekty jako wartości słownikowe i planujesz zmodyfikować je później w zwróconym słowniku bez klucza, musisz wykonać głęboką kopię.
Z płytką kopią:
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}
Z głęboką kopią:
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}