มีคำตอบที่ดีมากมาย แต่ฉันต้องการเน้นสิ่งหนึ่ง
คุณสามารถใช้ทั้ง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
ตรวจสอบจะเร็วขึ้นเล็กน้อยเนื่องจากpop()
เป็นฟังก์ชั่นที่มีภาวะแทรกซ้อนของตัวเองทำให้เกิดค่าใช้จ่าย มักจะไม่ใช่กรณีดังนั้นpop()
ค่าเริ่มต้นก็ดีพอ
สำหรับคำถามหลักคุณจะต้องทำสำเนาพจนานุกรมของคุณเพื่อบันทึกพจนานุกรมต้นฉบับและสร้างใหม่โดยไม่ต้องลบกุญแจ
บางคนที่นี่แนะนำให้ทำสำเนาเต็มรูปแบบด้วยcopy.deepcopy()
ซึ่งอาจเป็น overkill สำเนา "ปกติ" (ตื้น) ใช้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}