[Python-3000] Iterators for dict keys, values, and items == annoying :)

Brett Cannon brett at python.org
Fri Mar 24 01:46:29 CET 2006


On 3/23/06, Guido van Rossum <guido at python.org> wrote:
> On 3/23/06, Ian Bicking <ianb at colorstudy.com> wrote:
> [Guido]
> > > Testing whether an iterator is empty or not is an oxymoron; the only
> > > legit way is to call next() and see whether it raises StopIteration.
> > > This is the fundamental confusion I am talking about. It is NOT
> > > "natural enough". It reveals a fundamental misunderstanding of the
> > > design of the iterator protocol.
> >
> > I'm talking about a use case, not the protocol.  Where iterators are
> > used, it is very common that you also want to distinguish between zero
> > and some items.
>
> Really? Methinks you are thinking of a fairly specific context -- when
> presenting database query results to a user. The problem IMO lies in
> SQLObject (which I admit I've never used) or perhaps in SQL itself, or
> the specific underlying DB. In most other situations, you have an
> honest-to-god container (e.g. a dict) which you can test for emptiness
> before even asking for an iterator over its items. When all you have
> is a query represented as an iterator this doesn't fly. That's why
> some DB API implementations return the number of results as the
> non-standard return value of the query API (at least that's what I
> recall -- it's been a while since I used the DB API).
>

I think there is a fundamental difference between your views of
iterators.  It sounds like Ian is viewing them as a separate object;
something that happens to have derived its values from a dict in the
situation begin discussed.  While it seems Guido views the iterator
for the dict as a view (ala Java in a way) of the data and providing
an object with an API for viewing that data.

And this leads to the difference between wanting to know the length of
the iterator compared to the object that returned the iterator. 
Taking the view of the iterator as its own object with data, you would
do::

  obj = {}
  it = obj.keys()
  len(it)

But taking the view of the iterator as a view of the original object,
it makes more sense to work off the original object::

  obj = {}
  len(obj)
  it = obj.keys()

I understand Ian's view since I know I like to pass around iterators
for use and that disconnects the iterator from the object that
generated it and thus makes it impossible to find out possible info on
the data contained without exhausting the iterator compared to just
performing data upon the object containing the original the data.

But I think if objects returned iterators instead of lists the
iterator-as-view will begin to be used more than viewing them as
iterator-has-own-data.  But this also means that making a more
view-like interface would be handy.  In terms of what would need to be
supported (len, deletion, etc.) I don't know.  I personally have not
had that much of a need since I then just pass the originating object
and get the iterator as needed instead of passing around the iterator.

-Brett


More information about the Python-3000 mailing list