Best way to pop many elements from a Python dict

Question:

This is my code:

a = dict(aa='aaaa', bb='bbbbb', cc='ccccc', ...)
print(a.pop(['cc', ...]))

but this raises an error.
What is the best simple way to pop many elements from a python dictionary?

Asked By: zjm1126

||

Answers:

How about the simple:

for e in ['cc', 'dd',...]: 
  a.pop(e)
Answered By: Himadri Choudhury

If I understand correctly what you want, this should do the trick:

print [a.pop(k) for k in ['cc', ...]]

Be careful, though, because pop is destructive, i.e. it modifies your dictionary.

Answered By: Vojislav Stojkovic

Using list comprehension:

a = {'key1':'value1','key2':'value2','key3':'value3'}
print [a.pop(key) for key in ['key1', 'key3']]
Answered By: Tomek Kopczuk
a={'aa':'aaaa','bb':'bbbbb','cc':'ccccc'}
remove = ['aa', 'cc']
newA = dict([(k, v) for k,v in a.items() if k not in remove])
Answered By: Mike Lewis

Here is a one-liner, that will work on arbitrary long dictionary, for this exact case:

print([a.pop(key) for key in list(a.keys()) if key >= 'cc'])

To illustrate:

a = dict(aa='aaaa', bb='bbbbb', cc='ccccc', dd='ddddd', ee='eeeee')
print([a.pop(key) for key in list(a.keys()) if key >= 'cc']) # => ['ccccc', 'ddddd', 'eeeee']
print(a) # => {'aa': 'aaaa', 'bb': 'bbbbb'}

Note: it’ll work as long as dictionary keys are “incremented” as follows: aa, bb, cc, dd, ee, ff, …

Answered By: user8554766

I’ve peformed a benchmark:

d = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
drop = ('a', 'b', 'x', 'y', 'z')

Test 1: d.pop(k, None). Note the second argument: it makes sure that missing keys don’t fail

for key in drop:
    d.pop(key, None)

Test 2: if key in d: d.pop(). Will this extra condition slow things down or improve the performance of .pop()?

for key in drop:
    if key in d:
        d.pop(key)

Test 3: bad set

bad = set(d) & set(drop)  # find bad keys to drop

for key in bad:
    del d[key]

Test 4: create a new dict as comprehension

d = {k: v for k, v in d.items() if k not in drop}

Results:

  • .pop(key, None): 4.37s
  • if key in d: pop(): 3.75s
  • if key in set(bad): del d[key]: 5.27s
  • comprehension: 7.2s

Conclusions:

  • Dict comprehension has the worst performance
  • del is not too good
  • Both .pop() solutions are fine. Don’t worry about an extra if: it actually improves things

Finally, Python is still able to 2 million times a second. Don’t worry about it much 🙂

Answered By: kolypto

your_dict.clear() might also be an option

Answered By: Maks

Nobody has shown how to subtract the popped pairs as a separate dict. Not explicitly in the question, but still answers the question (as shown below) and has the added value of the popped keys and values captured in a separate dict:

>>> a = dict(aa='aaaa', bb='bbbbb', cc='ccccc', dd='ddddd', ee='eeeee')
>>> subtracted = dict((key, a.pop(key)) for key in ['cc', 'dd'])

>>> a
{'aa': 'aaaa', 'bb': 'bbbbb', 'ee': 'eeeee'}

>>> print(subtracted)
{'cc': 'ccccc', 'dd': 'ddddd'}

>>> print(list(subtracted.values()))
['ccccc', 'ddddd']
Answered By: NeilG
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.