If an iterators were indexable, with non-decreasing order only, then first(it) would become a simple it[0]. with exactly the same semantics, except the possibilty of raising a (visible) IndexError on an exhausted iterator, instead of .

By "non decreasing" I mean the ability to do something like this:

    it = iter('abcd')
    for i in range(4):
        print(it[i])

Of course, it will force the iterator to have additional memory.
I am sure this was suggested before, probably many times (and obviously rejected), but not exactly in this specific context.
So, maybe allowing only it[0], or maybe generator[0], would be nice (even if it's just an ugly special case").

----
Elazar


2014-02-22 16:49 GMT+02:00 Oscar Benjamin <oscar.j.benjamin@gmail.com>:
>
> On 21 February 2014 18:00, Peter Otten <__peter__@web.de> wrote:
> > Oscar Benjamin wrote:
> >
> > I think we constantly have to deal with libraries that do almost but not
> > exactly what we want them to do. If you look at the code it is clear that
> > the author made a conscious design decision
> >
> >     @property
> >     def fieldnames(self):
> >         if self._fieldnames is None:
> >             try:
> >                 self._fieldnames = next(self.reader)
> >             except StopIteration:
> >                 pass
> >         self.line_num = self.reader.line_num
> >         return self._fieldnames
> >
> > totally unrelated to for loops catching StopIterations.
>
> I was aware of the code. If you look at the commit that made it that
> way then you can see that the previous implementation was a bare next.
> It's not clear to me that the behaviour was a design decision or an
> implementation accident that was propagated for backwards
> compatibility:
>
> $ hg blame Lib/csv.py | grep StopIteration
> 44735:             except StopIteration:
> $ hg log -p -r 44735 Lib/csv.py
> <snip>
> --- a/Lib/csv.py Sat Aug 09 12:47:13 2008 +0000
> +++ b/Lib/csv.py Sat Aug 09 19:44:22 2008 +0000
> @@ -68,7 +68,7 @@
>  class DictReader:
>      def __init__(self, f, fieldnames=None, restkey=None, restval=None,
>                   dialect="excel", *args, **kwds):
> -        self.fieldnames = fieldnames    # list of keys for the dict
> +        self._fieldnames = fieldnames   # list of keys for the dict
>          self.restkey = restkey          # key to catch long rows
>          self.restval = restval          # default value for short rows
>          self.reader = reader(f, dialect, *args, **kwds)
> @@ -78,11 +78,25 @@
>      def __iter__(self):
>          return self
>
> +    @property
> +    def fieldnames(self):
> +        if self._fieldnames is None:
> +            try:
> +                self._fieldnames = next(self.reader)
> +            except StopIteration:
> +                pass
> +        self.line_num = self.reader.line_num
> +        return self._fieldnames
> +
> +    @fieldnames.setter
> +    def fieldnames(self, value):
> +        self._fieldnames = value
> +
>      def __next__(self):
> +        if self.line_num == 0:
> +            # Used only for its side effect.
> +            self.fieldnames
>          row = next(self.reader)
> -        if self.fieldnames is None:
> -            self.fieldnames = row
> -            row = next(self.reader)
>          self.line_num = self.reader.line_num
>
>
>
> Peter wrote:
> >
> > I fail to see the fundamental difference between next(...) and
> > sequence[...]. There are edge cases you have to consider, and you add
> > comments where you expect them to help your readers to understand your
> > intentions.
>
> The difference is that it's not common practice to catch and ignore
> IndexError around large blocks of code e.g.:
>
> try:
>     do_loads_of_stuff()
> except IndexError:
>     pass
>
> However that is in effect what happens for StopIteration since a
> typical program will have loads of places where it gets silently
> caught. The difference is that StopIteration is a particularly
> innocuous error to leak.
>
>
> Cheers,
> Oscar
> _______________________________________________
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/