Самый быстрый способ удалить определенные ключи из dict в Python

Я ищу большую часть самого быстрого/эффективного способа удалить определенные ключи в 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 больше памяти. Я проверил свое предположение в некоторый маленький сравнительный тест.

Что-нибудь быстрее?

8
задан Brian Tompsett - 汤莱恩 6 July 2015 в 20:44
поделиться

2 ответа

Если dict достаточно велик, может иметь смысл вместо этого сгенерировать совершенно новый dict.

dict((k, v) for (k, v) in somedict.iteritems() if not k.startswith('someprefix'))
9
ответ дан 5 December 2019 в 07:33
поделиться

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 .

13
ответ дан 5 December 2019 в 07:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: