[Python-talk] Stability of dict.iteritems() (etc) under deletions

Mark Mc Mahon mark.m.mcmahon at gmail.com
Thu Apr 12 15:55:59 EDT 2007


Hi, Bill,

On 4/12/07, Bill Freeman <f at ke1g.mv.com> wrote:
> Assume that "d" is a dictionary below.  Is the following safe?
>
>   for k, v in d.iteritems():
>     if testFunction(v):
>       del d[k]
>
> or, equivalently:
>
>   for k in d.iterkeys():
>     if testFunction(d[k]):
>       del d[k]
>
> (I presume that the last one is equivalent to "for k in d:...".)
>

I had no idea, but the following would say that they are not safe...
>>> for x, y in d.items():
...     print x, y
...     del d[x]
...
1 1
2 2
3 3
4 4
>>> d
{}
>>> d = {1:1, 2:2, 3:3, 4:4}
>>> for x, y in d.iteritems():
...     print x, y
...     del d[x]
...
1 1
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
RuntimeError: dictionary changed size during iteration
>>> d
{2: 2, 3: 3, 4: 4}
>>> for x in d.iterkeys():
...     print x
...     del d[x]
...
2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
RuntimeError: dictionary changed size during iteration

> That is, does the deletion within the loop invalidate the
> iterator, or at least can prevent it from correctly returning
> the remainder of the items (e.g.; some might not be visited, some
> already visited might be visited again)?
>
> On the other hand, I presume that the following is safe:
>
>   for k, v in d.items():
>     if testFunction(d[k]):
>       del d[k]
>
>  - because items has returned a list object that is no longer
> tied to the dictionary by the time the first iteration runs.
>

As you can see above - that worked.

Mark


> Bill
> _______________________________________________
> Python-talk mailing list
> Python-talk at dlslug.org
> http://dlslug.org/mailman/listinfo/python-talk
>


More information about the Python-talk mailing list