En Sun, 18 Oct 2009 19:53:20 -0200, Eloff <dan.el...@gmail.com> escribió:

On Oct 16, 7:38 pm, Carl Banks <pavlovevide...@gmail.com> wrote:

You would burden everyone who writes a custom iterator to provide a
__getitem__ method just because you're too lazy to type out the word
islice?

No, of course not. That would be stupid. Custom iterators are
iterators, so they would also get the default __getitem__ which would
work just perfectly for them. If they needed to override it, they
could. Remember, my proposal was to add a default __getitem__ for
iterators that is really just islice.

Note that iterators don't have a common base class - so where would such __getitem__ reside? *Anything* with a next/__next__ method is an iterator. In some, very limited cases, you can 'inject' a __getitem__ method into an existing iterator:

py> from itertools import islice
py>
py> def __getitem__(self, subscript):
...   if isinstance(subscript, slice):
... return islice(self, subscript.start, subscript.stop, subscript.step)
...   elif isinstance(subscript, int):
...     return next(islice(self, subscript, subscript+1, 1))
...
py> def add_slice_support(iterator):
...   oldtype = type(iterator)
... newtype = type(oldtype.__name__, (oldtype,), {'__getitem__': __getitem__})
...   iterator.__class__ = newtype
...   return iterator

Unfortunately this only works for user-defined iterators:

py> add_slice_support(range(30))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in add_slice_support
TypeError: __class__ assignment: only for heap types

And even then, there are surprises:

py> class Foo(object):
...   i = 0
...   def __iter__(self): return self
...   def next(self):
...     ret, self.i = self.i, self.i+1
...     return ret
...
py> it = add_slice_support(Foo())
py> print it[2]
2
py> for z in it[5:10]: print z
...
8   # 8???
9
10
11
12
py> for z in it[5:10]: print z
...
18  # 18???
19
20
21
22
py>

The main use case I'm thinking about here is skipping elements or
limiting results from iterators, usually in for loops:

for x in my_iter[5:]:
    ...

for x in my_iter[:5]:
    ...

Clearly that's easier and more readable than using islice. Nobody has
yet to provide a concrete reason why that would be a _bad thing_. That
doesn't make it a _good thing_, either.

You'll have to remember to never reuse my_iter again, as my example above shows. Or keep track of the past items so you can adjust the indices. But anyway you can't retrieve those past items, unless you maintain them all in a list and take the memory penalty. Or just use islice when needed - only six letters, and you avoid all those problems... ;)

--
Gabriel Genellina

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to