在Python中快速删除字典中特定键的方法
我在寻找在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'))