Có rất nhiều câu trả lời hay, nhưng tôi muốn nhấn mạnh một điều.
Bạn có thể sử dụng cả dict.pop()
phương thức và del
câu lệnh chung hơn để xóa các mục khỏi từ điển. Cả hai đều biến đổi từ điển gốc, vì vậy bạn cần tạo một bản sao (xem chi tiết bên dưới).
Và cả hai sẽ nâng lên KeyError
nếu khóa bạn cung cấp cho họ không có trong từ điển:
key_to_remove = "c"
d = {"a": 1, "b": 2}
del d[key_to_remove] # Raises `KeyError: 'c'`
và
key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove) # Raises `KeyError: 'c'`
Bạn phải chăm sóc điều này:
bằng cách nắm bắt ngoại lệ:
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)
và
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)
bằng cách thực hiện kiểm tra:
key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
del d[key_to_remove]
và
key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
d.pop(key_to_remove)
nhưng pop()
cũng có một cách ngắn gọn hơn nhiều - cung cấp giá trị trả về mặc định:
key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove, None) # No `KeyError` here
Trừ khi bạn sử dụng pop()
để lấy giá trị của khóa bị xóa, bạn có thể cung cấp mọi thứ, không cần thiết None
. Mặc dù có thể là việc sử dụng del
với in
kiểm tra nhanh hơn một chút do pop()
là một chức năng với các biến chứng của chính nó gây ra chi phí. Thông thường không phải vậy, vì vậy pop()
với giá trị mặc định là đủ tốt.
Đối với câu hỏi chính, bạn sẽ phải tạo một bản sao của từ điển của mình, để lưu từ điển gốc và có một từ mới mà không cần xóa khóa.
Một số người khác ở đây đề nghị tạo một bản sao đầy đủ (sâu) copy.deepcopy()
, có thể là một bản sao quá mức, một bản sao "bình thường" (nông), sử dụng copy.copy()
hoặcdict.copy()
, có thể là đủ. Từ điển giữ một tham chiếu đến đối tượng làm giá trị cho khóa. Vì vậy, khi bạn xóa khóa khỏi từ điển, tham chiếu này sẽ bị xóa, không phải đối tượng được tham chiếu. Bản thân đối tượng có thể được xóa tự động sau đó bởi trình thu gom rác, nếu không có tài liệu tham khảo nào khác cho nó trong bộ nhớ. Tạo một bản sao sâu đòi hỏi nhiều tính toán hơn so với bản sao nông, do đó nó làm giảm hiệu suất mã bằng cách tạo bản sao, lãng phí bộ nhớ và cung cấp nhiều công việc hơn cho GC, đôi khi bản sao nông là đủ.
Tuy nhiên, nếu bạn có các đối tượng có thể thay đổi làm giá trị từ điển và có kế hoạch sửa đổi chúng sau này trong từ điển được trả về mà không có khóa, bạn phải tạo một bản sao sâu.
Với bản sao nông:
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}
Với bản sao sâu:
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}