[Python-3000] Iterators for dict keys, values, and items == annoying :)
Guido van Rossum
guido at python.org
Fri Mar 24 20:03:55 CET 2006
On 3/24/06, Tim Peters <tim.peters at gmail.com> wrote:
> There's one other common surprise in Zope-land, namely that
>
> for key in b.keys():
> ... possibly try to delete `key` from `b`
>
> "doesn't work" when `b` is a BTree. The _expectation_, derived from
> experience with Python dicts, is that it's bulletproof, but that's
> again because dict.keys() has returned a distinct list and BTrees were
> just different that way.
The Java collections framework actually has an API and an idiom that
make this work: ther's a method on the *iterator* that deletes the
current item without disturbing the iteration. The iterator is
required to maintain enough state to know whether deletion is
currently valid -- it's not before you've started iterating, or after
the iterator is exhausted, or if you've already deleted the item.
Deleting the item does not automatically move to the next item; you
must still call next() for that.
Clearly this requires careful cooperation between the iterator and the
container! For Python sets and dicts, it would be sufficient to
guarantee not to rehash upon such a deletion. For lists, it would
require the iterator to remember not to increment the index on the
subsequent next() call.
Java has a few flavors of iterators; for lists it also has an extended
iterator that allows moving back, and of course it also has iterators
that don't support deletion for whatever reason. It's a really neat
API!
Note that this is all quite independent from the views proposal (also
inspired by Java).
--
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-3000
mailing list