title: python - recursively deleting dict keys?
body: <p>I'm using Python 2.7 with <code>plistlib</code> to import a .plist in a nested dict/array form, then look for a particular key and delete it wherever I see it.</p>
  
  <p>When it comes to the actual files we're working with in the office, I already know where to find the values -- but I wrote my script with the idea that I didn't, in the hopes that I wouldn't have to make changes in the future if the file structure changes or we need to do likewise to other similar files.</p>
  
  <p>Unfortunately I seem to be trying to modify a dict while iterating over it, but I'm not certain how that's actually happening, since I'm using <code>iteritems()</code> and <code>enumerate()</code> to get generators and work with those instead of the object I'm actually working with.</p>
  
  <pre><code>def scrub(someobject, badvalue='_default'): ##_default isn't the real variable
      """Walks the structure of a plistlib-created dict and finds all the badvalues and viciously eliminates them.
  
  Can optionally be passed a different key to search for."""
      count = 0
  
      try:
          iterator = someobject.iteritems()
      except AttributeError:
          iterator = enumerate(someobject)
  
      for key, value in iterator:
          try:
              scrub(value)
          except:
              pass
          if key == badvalue:
              del someobject[key]
              count += 1
  
      return "Removed {count} instances of {badvalue} from {file}.".format(count=count, badvalue=badvalue, file=file)
  </code></pre>
  
  <p>Unfortunately, when I run this on my test .plist file, I get the following error:</p>
  
  <pre><code>Traceback (most recent call last):
    File "formscrub.py", line 45, in &lt;module&gt;
      scrub(loadedplist)
    File "formscrub.py", line 19, in scrub
      for key, value in iterator:
  RuntimeError: dictionary changed size during iteration
  </code></pre>
  
  <p>So the problem might be the recursive call to itself, but even then shouldn't it just be removing from the original object? I'm not sure how to avoid recursion (or if that's the right strategy) but since it's a .plist, I do need to be able to identify when things are dicts or lists and iterate over them in search of either (a) more dicts to search, or (b) the actual key-value pair in the imported .plist that I need to delete.</p>
  
  <p>Ultimately, this is a <em>partial</em> non-issue, in that the files I'll be working with on a regular basis have a known structure. However, I was really hoping to create something that doesn't care about the nesting or order of the object it's working with, as long as it's a Python dict with arrays in it.</p>