MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Python删除字典键值对的方法

2022-07-022.5k 阅读

使用 del 关键字删除字典键值对

在Python中,del 关键字是一个非常基础且强大的工具,用于删除各种对象,其中就包括字典中的键值对。其基本语法为:del dictionary[key],这里 dictionary 是你要操作的字典,key 是你想要删除的键。

假设我们有一个记录学生成绩的字典:

student_scores = {
    'Alice': 85,
    'Bob': 78,
    'Charlie': 92
}
del student_scores['Bob']
print(student_scores)

在上述代码中,我们使用 del student_scores['Bob'] 语句删除了键为 'Bob' 的键值对。之后打印 student_scores,输出结果为 {'Alice': 85, 'Charlie': 92},可以看到 'Bob': 78 这个键值对已被成功删除。

del 关键字在底层的实现机制主要涉及到字典内部的哈希表结构。字典本质上是基于哈希表实现的,当我们使用 del 删除一个键值对时,Python会根据键的哈希值定位到哈希表中对应的位置,然后将该位置的键值对标记为已删除(在一些实现中可能会进行物理删除或采用延迟删除策略)。这一过程会调整字典的大小以及相关的索引信息,以确保字典在后续操作中的一致性和正确性。

如果尝试删除一个不存在的键,Python会抛出 KeyError 异常:

student_scores = {
    'Alice': 85,
    'Bob': 78,
    'Charlie': 92
}
try:
    del student_scores['David']
except KeyError:
    print("键 'David' 不存在于字典中")

在这个代码块中,由于字典 student_scores 中不存在键 'David',所以 del student_scores['David'] 这一行会引发 KeyError 异常,我们通过 try - except 语句捕获并处理了这个异常,打印出相应的提示信息。

使用 pop 方法删除字典键值对

字典的 pop 方法用于删除指定键的键值对,并返回该键对应的值。其语法为 dictionary.pop(key[, default]),其中 key 是要删除的键,default 是可选参数,当键不存在时返回的默认值。如果不提供 default 且键不存在,会抛出 KeyError 异常。

还是以学生成绩字典为例:

student_scores = {
    'Alice': 85,
    'Bob': 78,
    'Charlie': 92
}
score = student_scores.pop('Bob')
print(score)
print(student_scores)

上述代码中,student_scores.pop('Bob') 删除了键为 'Bob' 的键值对,并返回其对应的值 78,将该值赋给 score 变量。然后打印 score 得到 78,再次打印 student_scores 可以看到 'Bob': 78 已被删除,输出为 {'Alice': 85, 'Charlie': 92}

当键不存在时,如果没有提供 default 参数:

student_scores = {
    'Alice': 85,
    'Bob': 78,
    'Charlie': 92
}
try:
    score = student_scores.pop('David')
except KeyError:
    print("键 'David' 不存在于字典中")

这里尝试删除不存在的键 'David',会抛出 KeyError 异常,我们通过 try - except 捕获并处理了该异常。

而如果提供了 default 参数:

student_scores = {
    'Alice': 85,
    'Bob': 78,
    'Charlie': 92
}
score = student_scores.pop('David', '未找到该学生成绩')
print(score)

此时 student_scores.pop('David', '未找到该学生成绩') 由于键 'David' 不存在,会返回我们提供的默认值 '未找到该学生成绩' 并赋给 score,打印 score 就会得到这个默认值。

从底层原理来看,pop 方法在字典的哈希表结构上进行操作。它首先根据键的哈希值定位到哈希表中的位置,如果找到对应的键值对,则将其从哈希表中移除,并返回对应的值。在移除键值对后,字典同样会调整内部的索引和大小信息,以维持数据结构的完整性。

使用 popitem 方法删除字典键值对

popitem 方法用于随机删除字典中的一个键值对,并以元组的形式返回被删除的键值对。在Python 3.7 及之后的版本中,字典是有序的(按照插入顺序),popitem 方法会删除并返回字典中的最后一个键值对;在Python 3.6 及之前的版本中,字典无序,popitem 方法删除并返回的是任意一个键值对。

示例代码如下:

student_scores = {
    'Alice': 85,
    'Bob': 78,
    'Charlie': 92
}
item = student_scores.popitem()
print(item)
print(student_scores)

在Python 3.7 及之后的版本运行上述代码,popitem 会删除并返回字典中的最后一个键值对,例如输出可能是 ('Charlie', 92),再次打印 student_scores 会得到 {'Alice': 85, 'Bob': 78}

在Python 3.6 及之前的版本运行时,由于字典无序,返回的键值对是不确定的,但同样会从字典中删除该键值对。

popitem 方法在底层的实现依赖于字典的内部存储结构。它在哈希表中找到一个有效的键值对(在有序字典中按特定顺序,无序字典中随机),将其从哈希表中移除,并更新字典的大小和相关索引信息。然后将移除的键值对包装成元组返回。

通过条件筛选删除字典键值对

有时候,我们需要根据一定的条件来删除字典中的键值对。比如,在学生成绩字典中,我们想要删除所有成绩低于80分的学生记录。可以通过循环和条件判断来实现:

student_scores = {
    'Alice': 85,
    'Bob': 78,
    'Charlie': 92
}
keys_to_delete = []
for key, value in student_scores.items():
    if value < 80:
        keys_to_delete.append(key)
for key in keys_to_delete:
    del student_scores[key]
print(student_scores)

在上述代码中,我们首先创建了一个空列表 keys_to_delete 用于存储要删除的键。然后通过 for 循环遍历字典的键值对,使用 items 方法可以同时获取键和值。当成绩低于80分(value < 80)时,将对应的键添加到 keys_to_delete 列表中。最后,再通过一个循环遍历 keys_to_delete 列表,使用 del 关键字删除字典中对应的键值对。最终打印的 student_scores{'Alice': 85, 'Charlie': 92}'Bob': 78 这个键值对已被删除。

另外,我们也可以使用字典推导式来创建一个新的字典,该字典只包含满足条件的键值对,然后将原字典替换为新字典:

student_scores = {
    'Alice': 85,
    'Bob': 78,
    'Charlie': 92
}
student_scores = {key: value for key, value in student_scores.items() if value >= 80}
print(student_scores)

这里的字典推导式 {key: value for key, value in student_scores.items() if value >= 80} 会遍历原字典的所有键值对,只保留成绩大于等于80分的键值对,并创建一个新的字典。然后将原字典 student_scores 替换为这个新字典,最终输出同样为 {'Alice': 85, 'Charlie': 92}

清空字典所有键值对

如果需要删除字典中的所有键值对,将字典变为空字典,可以使用字典的 clear 方法。其语法非常简单,就是 dictionary.clear()

示例如下:

student_scores = {
    'Alice': 85,
    'Bob': 78,
    'Charlie': 92
}
student_scores.clear()
print(student_scores)

运行上述代码,student_scores.clear() 方法会删除字典中的所有键值对,此时再打印 student_scores,输出为 {},表示一个空字典。

从底层原理来看,clear 方法会重置字典内部的哈希表结构。它会释放哈希表中存储键值对的内存空间(在某些实现中可能是标记为可重用),并将字典的大小重置为0。这样,字典就回到了初始的空状态,等待新的键值对被插入。

在实际应用中,当我们完成了对一个字典数据的处理,不再需要其内容,但还希望保留字典对象以备后续使用时,clear 方法就非常有用。例如,在一个循环中多次使用同一个字典来存储不同批次的数据,每次循环开始前可以使用 clear 方法清空字典,避免数据残留导致的错误。

从嵌套字典中删除键值对

当字典中包含嵌套字典时,删除键值对会稍微复杂一些。例如,我们有一个记录班级学生成绩的字典,其中每个学生又有不同科目的成绩,形成了嵌套结构:

class_scores = {
    'Class1': {
        'Alice': {'Math': 85, 'English': 90},
        'Bob': {'Math': 78, 'English': 82}
    },
    'Class2': {
        'Charlie': {'Math': 92, 'English': 88}
    }
}

如果要删除 Class1AliceMath 成绩键值对,可以这样操作:

del class_scores['Class1']['Alice']['Math']
print(class_scores)

上述代码中,通过多层索引定位到要删除的键值对,即 class_scores['Class1']['Alice']['Math'],然后使用 del 关键字将其删除。打印 class_scores 可以看到 'Math': 85 这个键值对已从 Alice 的成绩字典中删除。

如果要删除整个 Alice 的成绩记录,可以这样:

del class_scores['Class1']['Alice']
print(class_scores)

这里通过 del class_scores['Class1']['Alice'] 删除了 Class1Alice 的整个成绩记录。

从底层原理来说,嵌套字典实际上是多个字典对象通过引用关系组合在一起。当我们删除嵌套字典中的键值对时,Python首先根据外层字典的键定位到内层字典对象,然后在内层字典中按照同样的哈希表操作方式删除指定的键值对。在删除过程中,会更新相关字典的内部状态,如大小和索引信息等,以保证数据结构的一致性。

注意事项及性能考量

  1. 键存在性检查:在使用 delpop 方法删除键值对时,如果不确定键是否存在,最好使用条件判断或捕获 KeyError 异常来避免程序出错。例如,在使用 del 时:
student_scores = {
    'Alice': 85,
    'Bob': 78,
    'Charlie': 92
}
key_to_delete = 'David'
if key_to_delete in student_scores:
    del student_scores[key_to_delete]
else:
    print(f"键 {key_to_delete} 不存在")

在使用 pop 方法时,可以通过提供 default 参数来避免异常:

student_scores = {
    'Alice': 85,
    'Bob': 78,
    'Charlie': 92
}
key_to_delete = 'David'
score = student_scores.pop(key_to_delete, '未找到该学生成绩')
print(score)
  1. 性能方面:对于小型字典,不同删除方法在性能上的差异可能不明显。但对于大型字典,del 关键字和 pop 方法在删除单个键值对时通常具有较好的性能,因为它们直接操作字典的内部结构。而 popitem 方法由于涉及到定位要删除的键值对(在无序字典中随机,有序字典中按顺序),性能可能会稍差一些。

在通过条件筛选删除键值对时,如果使用循环遍历字典并删除,要注意每次删除操作可能会改变字典的大小和索引,可能影响循环的正确性。使用字典推导式创建新字典的方式虽然代码简洁,但会占用额外的内存来创建新字典,对于非常大的字典可能不太适合。

clear 方法在清空字典时性能较高,因为它只需要重置字典的内部状态,而不需要逐个删除键值对。

在从嵌套字典中删除键值对时,由于涉及多层索引和多个字典对象的操作,性能可能会受到一定影响,特别是当嵌套层次较深时。在这种情况下,要仔细设计代码逻辑,尽量减少不必要的索引操作和对象访问,以提高性能。

总之,在选择删除字典键值对的方法时,要综合考虑键的存在性、字典的大小、嵌套结构以及性能要求等因素,选择最合适的方法来确保程序的正确性和高效性。