在Python中快速删除字典中特定键的方法

10 投票
2 回答
16756 浏览
提问于 2025-04-16 00:11

我在寻找在Python字典中删除某些键的最快、最有效的方法。

这里有一些选择:

for k in somedict.keys(): 
    if k.startswith("someprefix"): 
        del somedict[k]

或者

dict((k, v) for (k, v) in somedict.iteritems() if not k.startswith('someprefix'))

从逻辑上讲,第一个代码片段在处理小字典时应该更快,因为它不会创建字典的副本,而是生成一个包含所有键的列表。不过,它需要进行两次查找和重建字典,这样会比较耗时。而第二个方法在处理大字典时更快,但需要使用两倍的内存。

有没有更快的方法呢?

2 个回答

18

不仅是 del 更容易理解,而且它的速度似乎比 pop() 稍微快一点:

$ python -m timeit -s "d = {'f':1,'foo':2,'bar':3}" "for k in d.keys():" "  if k.startswith('f'):" "    del d[k]"
1000000 loops, best of 3: 0.733 usec per loop

$ python -m timeit -s "d = {'f':1,'foo':2,'bar':3}" "for k in d.keys():" "  if k.startswith('f'):" "    d.pop(k)"
1000000 loops, best of 3: 0.742 usec per loop

补充说明:感谢 Alex Martelli 提供了如何进行这个性能测试的指导。希望我没有哪里出错。

首先测量复制所需的时间:

$ python -m timeit -s "d = {'f':1,'foo':2,'bar':3}" "d1 = d.copy()"
1000000 loops, best of 3: 0.278 usec per loop

在复制的字典上进行基准测试:

$ python -m timeit -s "d = {'f':1,'foo':2,'bar':3}" "d1 = d.copy()" "for k in d1.keys():" "  if k.startswith('f'):" "    del d1[k]"
100000 loops, best of 3: 1.95 usec per loop

$ python -m timeit -s "d = {'f':1,'foo':2,'bar':3}" "d1 = d.copy()" "for k in d1.keys():" "  if k.startswith('f'):" "    d1.pop(k)"
100000 loops, best of 3: 2.15 usec per loop

扣除复制的时间后,pop() 的时间是 1.872 微秒,而 del 的时间是 1.672 微秒。

9

如果字典(dict)很大,可能更合理的做法是生成一个全新的字典。

dict((k, v) for (k, v) in somedict.iteritems() if not k.startswith('someprefix'))

撰写回答