How about adding slice notation to iterators/generators?

Jaime Buelta jaime.buelta at gmail.com
Tue Oct 20 11:01:08 CEST 2009


El 16/10/2009 3:29, Eloff escribió:
> I was just working with a generator for a tree that I wanted to skip
> the first result (root node.)
>
> And it occurs to me, why do we need to do:
>
> import sys
> from itertools import islice
>
> my_iter = islice(my_iter, 1, sys.maxint)
>
> When we could simply add slice operations to generators?
>
> for x in my_iter[1:]:
>      pass
>
> The way I figure it, only if there is no __getitem__ defined, and the
> object has an __iter__ (i.e. not a list, but a iter(list) would be
> ok), then there should be a default __getitem__ that is really just
> islice, with similar limitations (no negative indices.)
>
> The idea might need a bit of polish, but fundamentally it seems like
> it could make it easier to deal with slicing generators?
>
> At the least, stop=sys.maxint, step=1, and islice needs to accept
> kwargs. So you could do islice(my_iter, start=1), that's an oversight
> imho.

I think the only way not to complicate more the design of iterators
will be to make equivalent

my_iter[start:n:end]

to an iterator more or less this way (just syntactic sugar)

iter = my_iter()
for i in range(start):
  next(iter)

for i in range(start,end):
  value = next(iter)
  if i % n == 0:
    yield value

Unfortunatelly, to get the last one you have to iterate completely the
iterator, but these are the rules of the game...

Adding a __getitem__ seems pointless to me. Iterators are enough
complicated the way they are, it's not so simple when you see them the
first time.

Also, I think that the language must somehow difference between
iterators and container, as they are different concepts. You can
always do something like

for i in list(iterator)[5:10]:
   do things

while it can be less efficient and less clean.

I don't know, could be worth discussing it... ;-)



More information about the Python-list mailing list