ลบองค์ประกอบจากพจนานุกรม


1392

มีวิธีลบรายการจากพจนานุกรมใน Python หรือไม่?

นอกจากนี้ฉันจะลบรายการออกจากพจนานุกรมเพื่อส่งคืนสำเนาได้อย่างไร (เช่นไม่แก้ไขต้นฉบับ)


13
ทำไมคุณถึงต้องการฟังก์ชั่นที่ส่งคืนพจนานุกรมเมื่อคุณสามารถแก้ไขพจนานุกรมได้โดยตรง?
amillerrhodes

5
พจนานุกรมpopวิธีการเปลี่ยนแปลงพจนานุกรมในสถานที่ ดังนั้นจึงมีการเปลี่ยนแปลงการอ้างอิงไปยังพจนานุกรมที่ส่งผ่านจากผู้เรียกไปยัง "ฟังก์ชั่นผู้ช่วย" ดังนั้น "ฟังก์ชันตัวช่วย" จึงไม่จำเป็นต้องส่งคืนสิ่งใดเลยเนื่องจากการอ้างอิงดั้งเดิมไปยังพจนานุกรมในผู้โทรจะถูกเปลี่ยนแปลง อย่ากำหนดสิ่งตอบแทนจากdict.pop()สิ่งใดหากคุณไม่ต้องการ do stuff with my_dict; my_dict.pop(my_key, None); do more stuff with my_dict # now doesn't have my_keyEG: ใช้deepcopy(my_dict)ถ้าจำเป็น
Mark Mikofski

1
เนื่องจากชื่อดั้งเดิมไม่เห็นด้วยกับรายละเอียดและไม่รวมโซลูชันที่ชัดเจนโดยเฉพาะd.pop()ฉันจึงแก้ไขชื่อเพื่อถามคำถามที่ระบุในรายละเอียด
smci

1
เราควรเพิ่มข้อแม้ถามว่าคุณจริงๆต้องการทำเช่นนี้เช่นถ้าคุณทำมันไม่มีครั้งในพจนานุกรมที่มีองค์ประกอบ E คุณจะรั่วไหล (/ ใช้งาน) O (N * E) หน่วยความจำกับทุกสำเนาลึก ถ้าคุณเพียงต้องการอ่านอย่างเดียว (คัดลอกตื้น) d.pop(key)ทำ แต่ถ้าสิ่งใดที่เคยปรับเปลี่ยนสำเนาตื้นคุณมีปัญหาที่รู้จักกันดีกับ aliasing ช่วยถ้าคุณบอกเราถึงบริบทที่กว้างขึ้น (มีอะไรอีกที่เคยปรับเปลี่ยนค่า dict หรือไม่คุณกำลังพยายามที่จะทำซ้ำแบบทำลายล้างในรายการหรือไม่ถ้าไม่ใช่อะไร?)
smci

5
"ทำไมคุณถึงต้องการฟังก์ชั่นที่ส่งคืนพจนานุกรมเมื่อคุณสามารถแก้ไขพจนานุกรมได้โดยตรง?" อาจเป็นเพราะคุณต้องการเขียนฟังก์ชั่นแท้ที่ไม่ได้แก้ไขพารามิเตอร์ของพวกเขา?
ยีนสิทธิชัย

คำตอบ:


1726

delงบเอาองค์ประกอบ:

del d[key]

อย่างไรก็ตามสิ่งนี้จะกลายเป็นพจนานุกรมที่มีอยู่ดังนั้นเนื้อหาของพจนานุกรมจะเปลี่ยนแปลงสำหรับใครก็ตามที่มีการอ้างอิงถึงอินสแตนซ์เดียวกัน หากต้องการส่งคืนพจนานุกรมใหม่ให้ทำสำเนาของพจนานุกรม:

def removekey(d, key):
    r = dict(d)
    del r[key]
    return r

dict()คอนสตรัคทำให้สำเนาตื้น เมื่อต้องการทำสำเนาลึกให้ดูที่โมดูลcopy


โปรดทราบว่าการทำสำเนาทุก dict del/ assignment / etc หมายความว่าคุณกำลังไปจากเวลาคงที่ถึงเวลาเชิงเส้นและใช้พื้นที่เชิงเส้น สำหรับ dicts ขนาดเล็กนี่ไม่ใช่ปัญหา แต่ถ้าคุณวางแผนที่จะทำสำเนาขนาดใหญ่จำนวนมากคุณอาจต้องการโครงสร้างข้อมูลที่แตกต่างกันเช่น HAMT (ดังอธิบายในคำตอบนี้ )


15
เป็นจุดที่ดีมากเกี่ยวกับความผันแปรของพจนานุกรม +1 - แม้ว่าฉันไม่สามารถนึกถึงเวลาที่ฉันต้องการสำเนาของพจนานุกรมได้ฉันก็มักจะใช้สำเนา 'ทุกคน' เหมือนกัน จุดที่ดี
tMC

30
@tMC หากคุณแก้ไขสิ่งdictที่คุณวนลูปมันจะทำให้คุณเกิดข้อผิดพลาด:RuntimeError: dictionary changed size during iteration
VertigoRay

15
สิ่งที่เกี่ยวกับpopวิธีการซึ่งในความเป็นจริงไม่เหมือนกัน มันไม่ได้เป็น pythonic มากขึ้น? (เป็นวิธี dict ไม่ใช่คำสงวนพิเศษ)
Serge

21
คำตอบนี้มีจุดอ่อนมันอาจทำให้เข้าใจผิด ผู้อ่านอาจเข้าใจผิดว่า dict (d) สามารถให้สำเนาด้วย 'd' แต่มันเป็นสำเนาที่ไม่สมบูรณ์ เมื่อทำการเดลคีย์เท่านั้นก็ถือว่าใช้ได้ แต่เมื่อคุณต้องการทำอย่างอื่นกับ dict ที่ซ้อนกันการแก้ไข 'r' โดยใช้วิธีการคัดลอกนั้นอาจทำให้เกิดการเปลี่ยนแปลง 'd' ดั้งเดิม ในการรับสำเนาที่แท้จริงคุณต้อง 'นำเข้าสำเนา' ก่อนจากนั้น 'r = copy.deepcopy (d)'
Zen

10
@ เซน: ยุติธรรมมากพอฉันได้เพิ่มข้อความเกี่ยวกับสำเนาตื้นและลึก
Greg Hewgill

264

pop กลายพันธุ์พจนานุกรม

 >>> lol = {"hello": "gdbye"}
 >>> lol.pop("hello")
     'gdbye'
 >>> lol
     {}

หากคุณต้องการเก็บต้นฉบับคุณสามารถคัดลอกได้


29
"del" ก็โอเค แต่ "pop" ดูเหมือนจะเป็น "Pythonic" มากกว่าในความคิดของฉัน
ivanleoncz

1
@ivanleoncz ทำไม
kevr

3
popส่งคืนค่าที่ 'popped' ซึ่งช่วยให้คุณใช้ค่านี้ได้ไม่ว่าด้วยเหตุผลใดเพิ่มเติม ถ้าไม่ใช่ "Pythonic" มากกว่านี้ฉันจะบอกว่ามันดูดีขึ้นแน่นอน :) มันไม่ใช่ dict แต่มันใช้วิธีเดียวกันกับทั้ง: github.com/ivanlmj/python-prototypes/blob/master/3.4/…
ivanleoncz

2
@ivanleoncz นอกจากนี้ยังมีเหตุผลที่ดีกว่าอีกหนึ่งข้อที่popสามารถให้กับค่าเริ่มต้นที่จะส่งคืนเมื่อไม่มีคีย์จาก dict เป็นเรื่องที่ดีเมื่อคุณต้องการลบคีย์บางปุ่ม แต่บางปุ่มอาจหายไป delจะโยนKeyErrorในกรณีเช่นนี้
itachi

80

ฉันคิดว่าทางออกของคุณเป็นวิธีที่ดีที่สุด แต่ถ้าคุณต้องการโซลูชันอื่นคุณสามารถสร้างพจนานุกรมใหม่ด้วยการใช้คีย์จากพจนานุกรมเก่าโดยไม่รวมคีย์ที่คุณระบุดังนี้:

>>> a
{0: 'zero', 1: 'one', 2: 'two', 3: 'three'}
>>> {i:a[i] for i in a if i!=0}
{1: 'one', 2: 'two', 3: 'three'}

2
เจ๋งจริงๆ ฉันชอบวิธีที่รวดเร็วในการกรองพจนานุกรมโดยไม่ต้องกำหนดฟังก์ชั่นใหม่
Joe J

6
สำหรับผู้ที่ไม่คุ้นเคยกับความเข้าใจคุณสามารถทำสิ่งนี้: {i:a[i] for i in a if i not in [0, 1, 2]}หากคุณต้องการลบองค์ประกอบหลายอย่าง
kmatheny

9
{k:v for k,v in a.items() if k != 0}ฉันจะคิดว่าดีกว่า
rlbond

1
ทางออกที่ดีที่สุดสำหรับการลบรายการด้วยคีย์และส่งคืนผลลัพธ์ของ dict ใหม่ในบรรทัดเดียวกัน ตัวอย่างเช่นหากคุณจำเป็นต้องใช้นักการ Dict สร้างอยู่แล้วโดยไม่ต้องมีรายการเดียว**kwargs,some_function(**{k:v for k,v in some_dict.items() if k not 'some_key'})
โคล

ทางออกที่ดีที่สุดที่นี่ หนึ่งซับและมันไม่ได้กลายพันธุ์พจนานุกรมดั้งเดิม
Andrew Winterbotham

55

เดลคำสั่งคือสิ่งที่คุณกำลังมองหา หากคุณมีพจนานุกรมชื่อ foo ที่มีคีย์ชื่อ 'bar' คุณสามารถลบ 'bar' จาก foo ดังนี้:

del foo['bar']

โปรดทราบว่านี่เป็นการแก้ไขพจนานุกรมที่ดำเนินการอยู่อย่างถาวร หากคุณต้องการเก็บพจนานุกรมต้นฉบับคุณจะต้องสร้างสำเนาไว้ล่วงหน้า:

>>> foo = {'bar': 'baz'}
>>> fu = dict(foo)
>>> del foo['bar']
>>> print foo
{}
>>> print fu
{'bar': 'baz'}

การdictโทรทำสำเนาตื้น copy.deepcopyหากคุณต้องการสำเนาลึกการใช้งาน

นี่เป็นวิธีที่คุณสามารถคัดลอกและวางเพื่อความสะดวกของคุณ:

def minus_key(key, dictionary):
    shallow_copy = dict(dictionary)
    del shallow_copy[key]
    return shallow_copy

1
@ pythonian29033 จริงไม่มี คำตอบที่ได้รับการยอมรับทำงานได้ตามที่คาดหวัง - มันจะส่งคืนคำสั่งโดยไม่มีปุ่มเดียว วิธีการจากคำตอบนี้กลายพันธุ์ dict ดั้งเดิม;) มีความแตกต่างอย่างมีนัยสำคัญ
maxkoryukov

1
@ arussell84 ทำไม>>>มักใช้ในตัวอย่างของหลาม ใช่หลาม doc มีสิ่งต่าง ๆ มากมาย แต่รหัสดังกล่าวคือไม่สะดวกสำหรับ CopyPaste ฉันสับสน ...
maxkoryukov

@ maxkoryukov yup มันทำ! แต่ฟังก์ชั่นนั้นและคำตอบนี้เหมือนกันทุกประการยกเว้นว่าคำตอบนั้นอยู่ในฟังก์ชัน และคุณจะต้องไม่ได้รับการเข้ารหัสในหลามชั่วขณะ>>>เลียนแบบสัญกรณ์ฟังจากไพ ธ อนในโหมด cli
pythonian29033

2
@ pythonian29033 >>>เกี่ยวกับ ใช่มันเป็นสไตล์ REPL แต่เราจะพูดอย่างตรงไปตรงมา: มีเพียงคนเดียวเท่านั้นที่เขียนตัวอย่างนี้และ 1,000 คนอ่านสิ่งนี้ ฉันคิดว่ามันจะเป็นการดีถ้าเขียนตัวอย่างในแบบที่อนุญาตให้คัดลอกและเรียกใช้งานได้ง่าย ฉันไม่ต้องการลบวงเล็บมุมนี้ด้วยมือ หรือคัดลอกทีละบรรทัด .. ดังนั้นฉันไม่เข้าใจ: ทำไมมุมนี้ยังคงอยู่ที่นั่น))) อาจเป็นเพราะฉันไม่รู้อะไรเลย?
maxkoryukov

3
ฉันได้เพิ่มฟังก์ชั่นที่สามารถคัดลอก / วางเพื่อความสะดวกของคุณ
arussell84

48

มีคำตอบที่ดีมากมาย แต่ฉันต้องการเน้นสิ่งหนึ่ง

คุณสามารถใช้ทั้ง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}

20

... ฉันจะลบรายการจากพจนานุกรมเพื่อส่งคืนสำเนาได้อย่างไร (เช่นไม่แก้ไขต้นฉบับ)

A dictเป็นโครงสร้างข้อมูลที่ไม่ถูกต้องที่จะใช้สำหรับสิ่งนี้

แน่นอนว่าการคัดลอก dict และ popping จากงานลอกเลียนแบบและสร้าง dict ใหม่ด้วยความเข้าใจ แต่การทำสำเนาทั้งหมดนั้นต้องใช้เวลา - คุณได้แทนที่การดำเนินการเวลาคงที่ด้วยเวลาเชิงเส้น และสำเนาทั้งหมดนั้นยังมีชีวิตอยู่ในคราวเดียวใช้พื้นที่ - พื้นที่เชิงเส้นต่อสำเนา

โครงสร้างข้อมูลอื่น ๆ เช่นอาร์เรย์กัญชาแมปพยายามได้รับการออกแบบสำหรับตรงชนิดของกรณีการใช้งานนี้: การเพิ่มหรือลบองค์ประกอบผลตอบแทนสำเนาในเวลาลอการิทึมร่วมกันมากที่สุดของการจัดเก็บข้อมูลที่มีเดิม 1

แน่นอนว่ามีข้อเสียอยู่บ้าง ประสิทธิภาพเป็นลอการิทึมมากกว่าค่าคงที่ (แม้ว่าจะมีฐานขนาดใหญ่มักเป็น 32-128) และในขณะที่คุณสามารถทำให้ API ที่ไม่ใช่การกลายพันธุ์เหมือนกับ API dict"การกลายพันธุ์" นั้นแตกต่างกันอย่างเห็นได้ชัด และที่สำคัญที่สุดไม่มีแบตเตอรี่ HAMT ที่มาพร้อมกับ Python 2

pyrsistentห้องสมุดเป็นการนำของแข็งสวยของ HAMT ตาม Dict-ทดแทน (และประเภทอื่น ๆ ) สำหรับงูหลาม มันยังมีAPI Evolver ที่ดีสำหรับการย้ายรหัสการกลายพันธุ์ที่มีอยู่ไปยังรหัสถาวรอย่างราบรื่นที่สุด แต่ถ้าคุณต้องการชัดเจนเกี่ยวกับการส่งคืนสำเนามากกว่าการกลายพันธุ์คุณเพียงแค่ใช้มันในลักษณะนี้:

>>> from pyrsistent import m
>>> d1 = m(a=1, b=2)
>>> d2 = d1.set('c', 3)
>>> d3 = d1.remove('a')
>>> d1
pmap({'a': 1, 'b': 2})
>>> d2
pmap({'c': 3, 'a': 1, 'b': 2})
>>> d3
pmap({'b': 2})

นั่นd3 = d1.remove('a')คือสิ่งที่เป็นคำถามที่ถาม

หากคุณมีโครงสร้างข้อมูลที่ไม่แน่นอนเหมือนdictและlistฝังตัวอยู่ในpmapคุณจะยังคงมี aliasing ประเด็นที่คุณสามารถแก้ไขเพียงแค่นั้นโดยจะไม่เปลี่ยนรูปทั้งหมดลงวิธีการฝังpmapและpvectors


1. HAMT ได้กลายเป็นที่นิยมในภาษาเช่น Scala, Clojure, Haskell เพราะพวกเขาเล่นอย่างดีกับการเขียนโปรแกรมล็อคฟรีและหน่วยความจำทรานแซคชันของซอฟต์แวร์

2. ในความเป็นจริงมีเป็น HAMT ใน STDLIB contextvarsที่ใช้ในการดำเนินการ PEP ที่ถอนก่อนหน้านี้อธิบายว่าทำไม แต่นี่เป็นรายละเอียดการใช้งานที่ซ่อนอยู่ของไลบรารีไม่ใช่ประเภทคอลเล็กชันสาธารณะ



14

เพียงแค่เรียกเดล [[กุญแจ]]

อย่างไรก็ตามในการผลิตมันเป็นแนวปฏิบัติที่ดีในการตรวจสอบว่ามี 'key' อยู่ใน d หรือไม่

if 'key' in d:
    del d['key']

7
หืมในการผลิตมันเป็นการดีกว่าที่จะทำตามอุดมการณ์EAFP เพียงลบคีย์ในtry-exceptบล็อก อย่างน้อยนี่จะเป็นการปฏิบัติการปรมาณู;)
maxkoryukov

1
และถ้าคุณต้องการที่จะกระชับ - ใช้d.pop('key', None)มันเป็น oneliner แต่คำถามที่เกิดขึ้นจริงเกี่ยวกับการรับพจนานุกรมโดยไม่ต้องคีย์เดียวและไม่เกี่ยวกับการปรับเปลี่ยน dict ดังนั้นความเข้าใจ - เป็นตัวเลือกที่ดีที่นี่;)
maxkoryukov

7

ไม่ไม่มีวิธีอื่นนอกจากนี้

def dictMinus(dct, val):
   copy = dct.copy()
   del copy[val]
   return copy

อย่างไรก็ตามบ่อยครั้งที่การสร้างสำเนาของพจนานุกรมที่เปลี่ยนแปลงเพียงเล็กน้อยนั้นอาจไม่ใช่ความคิดที่ดีเพราะจะส่งผลให้ความต้องการหน่วยความจำขนาดใหญ่ โดยปกติแล้วจะเป็นการดีกว่าที่จะบันทึกพจนานุกรมเก่า (หากจำเป็น) จากนั้นแก้ไข



5
>>> def delete_key(dict, key):
...     del dict[key]
...     return dict
... 
>>> test_dict = {'one': 1, 'two' : 2}
>>> print delete_key(test_dict, 'two')
{'one': 1}
>>>

นี้ไม่ได้ทำจัดการข้อผิดพลาดใด ๆ ก็ถือว่าสำคัญคือใน Dict คุณอาจต้องการที่จะตรวจสอบว่าเป็นครั้งแรกและraiseถ้าไม่ได้


10
วิธีการของคุณแตกต่างจากแค่del test_dict[key]ไหน?
นักฟิสิกส์บ้า

5

นี่คือวิธีการออกแบบระดับบนสุด:

def eraseElement(d,k):
    if isinstance(d, dict):
        if k in d:
            d.pop(k)
            print(d)
        else:
            print("Cannot find matching key")
    else:
        print("Not able to delete")


exp = {'A':34, 'B':55, 'C':87}
eraseElement(exp, 'C')

ฉันส่งพจนานุกรมและคีย์ที่ฉันต้องการไปยังฟังก์ชันตรวจสอบว่าเป็นพจนานุกรมหรือไม่และถ้าคีย์นั้นใช้ได้และถ้ามีทั้งคู่ให้ลบค่าออกจากพจนานุกรมและพิมพ์ออกมาทางซ้าย

เอาท์พุท: {'B': 55, 'A': 34}

หวังว่าจะช่วย!


3

ตัวอย่างโค้ดด้านล่างจะช่วยให้คุณแน่นอนฉันได้เพิ่มความคิดเห็นในแต่ละบรรทัดซึ่งจะช่วยให้คุณเข้าใจรหัส

def execute():
   dic = {'a':1,'b':2}
   dic2 = remove_key_from_dict(dic, 'b')  
   print(dict2)           # {'a': 1}
   print(dict)            # {'a':1,'b':2}

def remove_key_from_dict(dictionary_to_use, key_to_delete):
   copy_of_dict = dict(dictionary_to_use)     # creating clone/copy of the dictionary
   if key_to_delete in copy_of_dict :         # checking given key is present in the dictionary
       del copy_of_dict [key_to_delete]       # deleting the key from the dictionary 
   return copy_of_dict                        # returning the final dictionary

หรือคุณสามารถใช้ dict.pop ()

d = {"a": 1, "b": 2}

res = d.pop("c")  # No `KeyError` here
print (res)       # this line will not execute

หรือวิธีที่ดีกว่าคือ

res = d.pop("c", "key not found")
print (res)   # key not found
print (d)     # {"a": 1, "b": 2}

res = d.pop("b", "key not found")
print (res)   # 2
print (d)     # {"a": 1}

2

นี่คือรูปแบบอื่นโดยใช้ความเข้าใจในรายการ:

original_d = {'a': None, 'b': 'Some'}
d = dict((k,v) for k, v in original_d.iteritems() if v)
# result should be {'b': 'Some'}

วิธีการจะขึ้นอยู่กับคำตอบจากโพสต์นี้: วิธีที่มีประสิทธิภาพในการลบคีย์ด้วยสตริงว่างจาก dict


1
หากคุณกำลังจะตอบคำถามอายุหลายปีที่มีคำตอบที่เรียบง่ายเหมาะสมและเป็นที่ยอมรับอย่างน้อยก็ต้องแน่ใจว่าคำตอบของคุณนั้นถูกต้อง สิ่งนี้ไม่ได้ทำตามที่ OP ร้องขอ
user2357112 รองรับ Monica

โดยทั่วไปฉันไม่ตรวจสอบวันที่เกี่ยวกับคำถามที่ฉันคิดว่าอาจมีข้อมูลที่มีค่าเพิ่มเข้าไป นอกจากนี้ต่อหนึ่งในการแสดงความคิดเห็นเกี่ยวกับคำถามที่ผมเชื่อมโยงกับ: "โดยปกติตรงนี้เป็นสิ่งที่คนต้องการและอาจเป็นสิ่งที่ตอบสนองความต้องการ OP แต่มันไม่ได้เป็นสิ่ง OP ถาม" stackoverflow.com/questions/12118695/...ฉัน รู้ว่ามันไม่ใช่คำตอบสำหรับคำถามโดยตรง ค่อนข้างจะขยายไปยังตัวเลือก
BigBlueHat

3
คำตอบนี้แม้ว่าจะไม่สมบูรณ์ให้เราเรียนรู้ว่าเราสามารถลบรายการด้วยหากเงื่อนไขเกินไป เพียงแค่เปลี่ยนif vเป็นif k is not 'a'คำตอบ op แต่ฉันไม่คิดว่ามันเป็นวิธีที่มีประสิทธิภาพสิ่งนี้จะลบองค์ประกอบใน O (n) มากกว่า O (log n) เหมือนที่ปรากฏหรือเดล
holgac

0
    species = {'HI': {'1': (1215.671, 0.41600000000000004),
  '10': (919.351, 0.0012),
  '1025': (1025.722, 0.0791),
  '11': (918.129, 0.0009199999999999999),
  '12': (917.181, 0.000723),
  '1215': (1215.671, 0.41600000000000004),
  '13': (916.429, 0.0005769999999999999),
  '14': (915.824, 0.000468),
  '15': (915.329, 0.00038500000000000003),
 'CII': {'1036': (1036.3367, 0.11900000000000001), '1334': (1334.532, 0.129)}}

รหัสต่อไปนี้จะทำสำเนาของ dict speciesและลบรายการที่ไม่ได้อยู่ในtrans_HI

trans_HI=['1025','1215']
for transition in species['HI'].copy().keys():
    if transition not in trans_HI:
        species['HI'].pop(transition)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.