Я ищу большую часть самого быстрого/эффективного способа удалить определенные ключи в Python dict
Вот некоторые опции
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'))
Логически первый отрывок должен быть быстрее на меньшем dicts, он не создает копию dict, но создает список всех ключей, однако двойное восстановление поисков и dict является трудоемким. В то время как второе быстрее на большем dicts, но требует 2x больше памяти. Я проверил свое предположение в некоторый маленький сравнительный тест.
Что-нибудь быстрее?
Если dict достаточно велик, может иметь смысл вместо этого сгенерировать совершенно новый dict.
dict((k, v) for (k, v) in somedict.iteritems() if not k.startswith('someprefix'))
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
Изменить: спасибо Алексу Мартелли за предоставление инструкций по проведению этого тестирования . Надеюсь, я нигде не ошибся.
Сначала измерьте время, необходимое для копирования:
$ python -m timeit -s "d = {'f':1,'foo':2,'bar':3}" "d1 = d.copy()"
1000000 loops, best of 3: 0.278 usec per loop
Тест для скопированного dict:
$ 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
Вычитая стоимость копирования, мы получаем 1,872 мксек для pop ()
и 1,672 мкс для del
.