良い答えはたくさんありますが、一つだけ強調したいと思います。
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
check を使用した方が若干高速になる可能性がありますが、pop()
オーバーヘッドが発生します。通常はそうではないのでpop()
、デフォルト値で十分です。
主な質問については、元の辞書を保存し、キーを削除せずに新しい辞書を作成するには、辞書のコピーを作成する必要があります。
他の一部の人は、で完全な(深い)コピーを作成することを提案しますcopy.deepcopy()
。これはやり過ぎかもしれませんが、copy.copy()
またはを使用した「通常の」(浅い)コピーでdict.copy()
十分かもしれません。辞書は、オブジェクトへの参照をキーの値として保持します。したがって、辞書からキーを削除すると、参照されているオブジェクトではなく、この参照が削除されます。メモリ内にオブジェクトへの参照が他にない場合、オブジェクト自体は後でガベージコレクタによって自動的に削除されます。ディープコピーを作成すると、シャローコピーに比べてより多くの計算が必要になるため、コピーを作成し、メモリを浪費し、GCにより多くの作業を提供することにより、コードのパフォーマンスが低下します。シャローコピーで十分な場合もあります。
ただし、ディクショナリ値として変更可能なオブジェクトがあり、返されたディクショナリでキーなしでそれらを後で変更する場合は、ディープコピーを作成する必要があります。
浅いコピー:
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}