1

Naivelly I would use:

for k, v in dictionary.items():
    if foo(v):
        del dictionary[k]

However this will cause an iterator exception as I edit the dictionary size while iterating over it. So how could I do this? - and especially, without making a copy of the dictionary, the copy approach:

copydict = dict(dictionary)
for k, v in copydict.items():
    if foo(v):
        del dictionary[k]

I wish to see how python would do such in place editing without actually using explicit iterators.

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
paul23
  • 8,799
  • 12
  • 66
  • 149

3 Answers3

3

Find all the keys to remove then delete after:

d = {1: 2, 3: 4, 5: 6}
remove = [k for k  in d if foo(d[k])]
for k in remove:
    del d[k]


In [38]: %%timeit
   ....: d = {1: 2, 3: 4, 5: 6}
   ....: matching_items = ((k, v) for k, v in list(d.items()) if v > 2)
   ....: d.clear()
   ....: d.update(matching_items)
   ....: 
100000 loops, best of 3: 2.85 µs per loop

In [40]: %%timeit
        d = {1: 2, 3: 4, 5: 6}
        remove =[k for k  in d if d[k]> 2]
        for k in remove:
           del d[k]
   ....: 
1000000 loops, best of 3: 873 ns per loop
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
  • I suspected mine was a bad idea, but you'd already nicked the good idea... was experimenting... thanks for the timeit's - have a +1 :) – Jon Clements Oct 25 '14 at 01:08
1

Here is an answer from a previous Stack Overflow question: Modifying a Python dict while iterating over it

dictionary.items() returns a view which can't be modified But if you iterate over list(dictionary.items()) you can modify the dictionary without the risk of iterator exception.

Community
  • 1
  • 1
cshortt
  • 176
  • 1
  • 7
0
for k, v in dictionary.viewkeys():
     if f(dictionary[k]):
         del dictionary[k]
flyingfoxlee
  • 1,764
  • 1
  • 19
  • 29