PEP 234: Iterators 
Author Message
 PEP 234: Iterators

Quote:

> >     - Using the same name for two different operations (getting an
> >       iterator from an object and making an iterator for a function
> >       with an sentinel value) is somewhat ugly.  I haven't seen a
> >       better name for the second operation though.

> I assume `ugly' refers to the implementation.

> As both operations return an iterator object it seems natural to use
> the same name for them. Having to remember two different names for
> iterator-returning operations looks ugly to me.

But the usage is typically different. iter(obj) will _usually_ be used from
within an __iter__ method, which will typically be invoked implicitly by the for
loop. I think it will be rare for iterators created "manually" with iter(obj) to
be passed "manually" to a for loop.

On the other hand, the output of iter(callable, sentinel) *is* likely to be
passed "manually" to a for loop.

Conceptually, iter(obj) returns an iterator object, and iter(callable, sentinel)
returns an object that can be iterated over. However, due to the protocol's
requirement that iter(obj) is equivalent to iter(iter(obj)) this duality is not
visible, and possibly therefore not that important. However, it *is* IMHO worthy
of the qualification "somewhat ugly", but not much more than that ;-)

Just



Sat, 18 Oct 2003 17:14:59 GMT  
 PEP 234: Iterators

Quote:
> > We could also add methods to dictionaries that return different kinds
> > of iterators

> Please do so.

>     for k, v in dict.itemiter():
>         ...

> is both more readable and more efficient than

>     for k in dict:
>         v = dict[k]
>         ...

> The item-iterator can also be passed around whereas the other form
> cannot.

Excellent argument!  I'll add it.

--Guido van Rossum (home page: http://www.python.org/~guido/)



Sat, 18 Oct 2003 20:44:37 GMT  
 PEP 234: Iterators
[PEP 234]

Quote:
> > >     - Using the same name for two different operations (getting an
> > >       iterator from an object and making an iterator for a function
> > >       with an sentinel value) is somewhat ugly.  I haven't seen a
> > >       better name for the second operation though.

[Christian Tanzer]

Quote:
> > I assume `ugly' refers to the implementation.

No, people were commenting that these were two very different pieces
of functionality rolled into one function.  Sort of like if len(x)
gave the length of a sequence and len(x, y) returned the greatest
common divisor of x and y.

Quote:
> > As both operations return an iterator object it seems natural to use
> > the same name for them. Having to remember two different names for
> > iterator-returning operations looks ugly to me.

Thanks -- I'll use that as an argument pro in the PEP.

[Just van Rossum]

Quote:
> But the usage is typically different. iter(obj) will _usually_ be used from
> within an __iter__ method, which will typically be invoked implicitly by the for
> loop. I think it will be rare for iterators created "manually" with iter(obj) to
> be passed "manually" to a for loop.
> On the other hand, the output of iter(callable, sentinel) *is* likely to be
> passed "manually" to a for loop.

The usages are indeed different, but not the way you describe.  I
wouldn't expect iter(obj) inside an __iter__() method -- this would
cause recursion, as iter(obj) calls obj.__iter__()!

The main use I see for iter(obj) is in cases like Tim's zipiter()
class.  I expect that folks used to functional programming will go
wild with the idea of writing functions that compose or slice and dice
iterators.  E.g. here's an iterator that gives the even-numbered items
of an argument iterator:

  class EvenIterator:

    def __init__(self, it):
      self.it = it

    def next(self):
      self.it.next()
      return self.it.next()

    def __iter__(self):
      return self

In order to use this, you need to pass it an iterator, not a sequence;
so if all you have is a sequence, you'd have to invoke iter() on it:

  >>> for i in EvenIterator(iter(range(10))):
        print i

  1
  3
  5
  7
  9
  >>>

Quote:
> Conceptually, iter(obj) returns an iterator object, and iter(callable, sentinel)
> returns an object that can be iterated over.

No.  iter(callable, sentinel) also returns an iterator.  Period.  I
don't see how adding "conceptually" changes this. :-)

Quote:
> However, due to the protocol's requirement that iter(obj) is
> equivalent to iter(iter(obj)) this duality is not visible, and
> possibly therefore not that important. However, it *is* IMHO worthy
> of the qualification "somewhat ugly", but not much more than that
> ;-)

:-)

--Guido van Rossum (home page: http://www.python.org/~guido/)



Sat, 18 Oct 2003 20:33:24 GMT  
 PEP 234: Iterators

Quote:
> I think it will be rare for iterators created "manually" with iter(obj) to
> be passed "manually" to a for loop.

And just to contradict you, my very first use of python iterators
did exactly that.  Of course, my iterator had special methods
set_start() and set_end() in order to make it start at a certain
position in the sequence and end at another.

My program was to download a set of web pages, indexed by a date
in the URL.  The next() method in the iterator generated the URL
for the next day, and I didn't want it to start trying to download
2000 years worth of web pages...  Thus I would do:

    ui = iter(obj)
    ui.set_start(2000,4,23)
    ui.set_end(2000,5,29)
    for url in ui:
        urlopen.urlretrieve(url)

to download the pages pertaining to dates between April 23rd and
May 29th, inclusive, last year.  (Actually, it is a bit more
complicated than that, but at least that is the gist of it.)

--
Thomas Bellman,   Lysator Computer Club,   Link?ping University,  Sweden

                             -- Mae West     !  Make Love -- Nicht Wahr!



Sun, 19 Oct 2003 03:01:05 GMT  
 PEP 234: Iterators


    [snip]

Quote:
> iterators.  E.g. here's an iterator that gives the even-numbered items
> of an argument iterator:

>   class EvenIterator:

>     def __init__(self, it):
>       self.it = it

If I understand the PEP correctly, wouldn't

        self.it = iter(it)

be better here?  Idempotent if 'it' is already an iterator, good if
'it' is a sequence instead?

Alex



Sun, 19 Oct 2003 03:42:24 GMT  
 PEP 234: Iterators

Quote:


> > I think it will be rare for iterators created "manually" with iter(obj) to
> > be passed "manually" to a for loop.

> And just to contradict you, my very first use of Python iterators
> did exactly that.  Of course, my iterator had special methods
> set_start() and set_end() in order to make it start at a certain
> position in the sequence and end at another.

> My program was to download a set of web pages, indexed by a date
> in the URL.  The next() method in the iterator generated the URL
> for the next day, and I didn't want it to start trying to download
> 2000 years worth of web pages...  Thus I would do:

>     ui = iter(obj)
>     ui.set_start(2000,4,23)
>     ui.set_end(2000,5,29)
>     for url in ui:
>         urlopen.urlretrieve(url)

> to download the pages pertaining to dates between April 23rd and
> May 29th, inclusive, last year.  (Actually, it is a bit more
> complicated than that, but at least that is the gist of it.)

Good show! Very nice example: I couldn't dream up a good alternative
spelling that doesn't prove me wrong ;-)

Just



Sun, 19 Oct 2003 04:35:38 GMT  
 PEP 234: Iterators
[Thomas Bellman]

Quote:
> ...
> My program was to download a set of web pages, indexed by a date
> in the URL.  The next() method in the iterator generated the URL
> for the next day, and I didn't want it to start trying to download
> 2000 years worth of web pages...  Thus I would do:

>     ui = iter(obj)
>     ui.set_start(2000,4,23)
>     ui.set_end(2000,5,29)
>     for url in ui:
>    urlopen.urlretrieve(url)

Oh dear. *Another* year 2**31 problem waiting to bite us!  I hope Python
3*10L**10 will eradicate the visible distinction between ints and longs by
then.

can't-be-in-favor-of-iterators-if-they-encourage-ints-ly y'rs  - tim



Sun, 19 Oct 2003 12:29:52 GMT  
 PEP 234: Iterators


Quote:

> > >     - Using the same name for two different operations (getting an
> > >       iterator from an object and making an iterator for a function
> > >       with an sentinel value) is somewhat ugly.  I haven't seen a
> > >       better name for the second operation though.

> > I assume `ugly' refers to the implementation.

> > As both operations return an iterator object it seems natural to use
> > the same name for them. Having to remember two different names for
> > iterator-returning operations looks ugly to me.

> But the usage is typically different. iter(obj) will _usually_ be used
> from within an __iter__ method, which will typically be invoked
> implicitly by the for loop. I think it will be rare for iterators
> created "manually" with iter(obj) to be passed "manually" to a for
> loop.

> On the other hand, the output of iter(callable, sentinel) *is* likely to be
> passed "manually" to a for loop.

The typical use of `iter(seq)' will certainly be implicit. OTOH, I'd
expect the number of explicit uses of `iter(seq)' to be comparable to
the number of explicit uses of `iter(callable, sentinel)'.

Quote:
> Conceptually, iter(obj) returns an iterator object, and iter(callable,
> sentinel) returns an object that can be iterated over.

That sentence is a refined example of hair splitting <wink>. The PEP
says that both return an iterator object. The fact that the iterator
object is constructed differently doesn't change the semantics of the
returned object.

Quote:
> However, it *is* IMHO worthy of the qualification "somewhat ugly", but
> not much more than that ;-)

I suffered languages which forced me to use different names for the
same operation applied to different data types (e.g., sort_int vs.
sort_float vs. sort_spam...) for too long. I very much appreciate
Ada's and C++'s concept of overloading. There are obvious reasons why
in general overloading doesn't work in Python.

So IMO the only plausible complaint about the overloading of `iter' is
that a Python user cannot do the same thing (the implementation of the
overloading probably earns the predicate `ugly', too, but that isn't
relevant for Python's users). I wouldn't go back to C++ to get
overloading back, though :-)

--

Glasauergasse 32                                       Tel: +43 1 876 62 36
A-1130 Vienna, Austria                                 Fax: +43 1 877 66 92



Sun, 19 Oct 2003 13:49:58 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. PEP 234: Iterators

2. PEP 234: Iterators

3. PEP 234: Iterators (fwd)

4. Discussion about PEP 234: iterators

5. PEP 234: Iterators (fwd)

6. PEP 234 little bug?

7. Jun for Java 234

8. API routine CryptEncrypt() returns error 234

9. PEP 276 Simple Iterator for ints (fwd)

10. PEP 276 Simple Iterator for ints (fwd)

11. PEP 276 Simple Iterator for ints

12. PEP 276 Simple Iterator for ints

 

 
Powered by phpBB® Forum Software